Using Laravel 8, I have a FormRequest Validation as followed
<?php
namespace App\Http\Requests\EXTERNAL;
use InfyOm\Generator\Request\APIRequest;
class ActionUpdateRequest extends APIRequest
{
public function rules(): array
{
return [
'data' => 'required',
];
}
public function messages(): array
{
return [
'data.required' => 'error.action.required.data',
];
}
}
When trying to call the endpoint that uses that request validation, I get this error
mb_strtoupper(): Argument #1 ($string) must be of type string, array given
After some digging around it appears the input key data
was the issue when it tries to replace the default error message by the one provided, replacing data
by anything else works properly but I can't find the root cause of it, any idea?
For reference, here is the full stack trace
[2025-03-04 13:30:31] local.ERROR: mb_strtoupper(): Argument #1 ($string) must be of type string, array given {"exception":"[object] (TypeError(code: 0): mb_strtoupper(): Argument #1 ($string) must be of type string, array given at /var/www/vendor/laravel/framework/src/Illuminate/Support/Str.php:732)
[stacktrace]
#0 /var/www/vendor/laravel/framework/src/Illuminate/Support/Str.php(732): mb_strtoupper(Array, 'UTF-8')
#1 /var/www/vendor/laravel/framework/src/Illuminate/Validation/Concerns/FormatsMessages.php(297): Illuminate\\Support\\Str::upper(Array)
#2 /var/www/vendor/laravel/framework/src/Illuminate/Validation/Concerns/FormatsMessages.php(220): Illuminate\\Validation\\Validator->replaceAttributePlaceholder('error.action.re...', Array)
#3 /var/www/vendor/laravel/framework/src/Illuminate/Validation/Validator.php(883): Illuminate\\Validation\\Validator->makeReplacements('error.action.re...', 'data', 'Required', Array)
#4 /var/www/vendor/laravel/framework/src/Illuminate/Validation/Validator.php(611): Illuminate\\Validation\\Validator->addFailure('data', 'Required', Array)
#5 /var/www/vendor/laravel/framework/src/Illuminate/Validation/Validator.php(416): Illuminate\\Validation\\Validator->validateAttribute('data', 'Required')
#6 /var/www/vendor/laravel/framework/src/Illuminate/Validation/Validator.php(447): Illuminate\\Validation\\Validator->passes()
#7 /var/www/vendor/laravel/framework/src/Illuminate/Validation/ValidatesWhenResolvedTrait.php(25): Illuminate\\Validation\\Validator->fails()
#8 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Providers/FormRequestServiceProvider.php(30): Illuminate\\Foundation\\Http\\FormRequest->validateResolved()
#9 /var/www/vendor/laravel/framework/src/Illuminate/Container/Container.php(1265): Illuminate\\Foundation\\Providers\\FormRequestServiceProvider->Illuminate\\Foundation\\Providers\\{closure}(Object(App\\Http\\Requests\\EXTERNAL\\ActionUpdateRequest), Object(Illuminate\\Foundation\\Application))
#10 /var/www/vendor/laravel/framework/src/Illuminate/Container/Container.php(1230): Illuminate\\Container\\Container->fireCallbackArray(Object(App\\Http\\Requests\\EXTERNAL\\ActionUpdateRequest), Array)
#11 /var/www/vendor/laravel/framework/src/Illuminate/Container/Container.php(1215): Illuminate\\Container\\Container->fireAfterResolvingCallbacks('App\\\\Http\\\\Reques...', Object(App\\Http\\Requests\\EXTERNAL\\ActionUpdateRequest))
#12 /var/www/vendor/laravel/framework/src/Illuminate/Container/Container.php(778): Illuminate\\Container\\Container->fireResolvingCallbacks('App\\\\Http\\\\Reques...', Object(App\\Http\\Requests\\EXTERNAL\\ActionUpdateRequest))
#13 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(853): Illuminate\\Container\\Container->resolve('App\\\\Http\\\\Reques...', Array, true)
#14 /var/www/vendor/laravel/framework/src/Illuminate/Container/Container.php(694): Illuminate\\Foundation\\Application->resolve('App\\\\Http\\\\Reques...', Array)
#15 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(838): Illuminate\\Container\\Container->make('App\\\\Http\\\\Reques...', Array)
#16 /var/www/vendor/laravel/framework/src/Illuminate/Routing/RouteDependencyResolverTrait.php(79): Illuminate\\Foundation\\Application->make('App\\\\Http\\\\Reques...')
#17 /var/www/vendor/laravel/framework/src/Illuminate/Routing/RouteDependencyResolverTrait.php(48): Illuminate\\Routing\\ControllerDispatcher->transformDependency(Object(ReflectionParameter), Array, Object(stdClass))
#18 /var/www/vendor/laravel/framework/src/Illuminate/Routing/RouteDependencyResolverTrait.php(28): Illuminate\\Routing\\ControllerDispatcher->resolveMethodDependencies(Array, Object(ReflectionMethod))
#19 /var/www/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(41): Illuminate\\Routing\\ControllerDispatcher->resolveClassMethodDependencies(Array, Object(App\\Http\\Controllers\\EXTERNAL\\ActionController), 'update')
#20 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(262): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(App\\Http\\Controllers\\EXTERNAL\\ActionController), 'update')
#21 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(205): Illuminate\\Routing\\Route->runController()
#22 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(721): Illuminate\\Routing\\Route->run()
#23 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#24 /var/www/vendor/acme-packages/laravel-api/src/Middlewares/VerifyApiKeyAccess.php(63): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#25 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Acme\\Api\\Middlewares\\VerifyApiKeyAccess->handle(Object(Illuminate\\Http\\Request), Object(Closure), 'update_action')
#26 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#27 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#28 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(127): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#29 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(103): Illuminate\\Routing\\Middleware\\ThrottleRequests->handleRequest(Object(Illuminate\\Http\\Request), Object(Closure), Array)
#30 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(55): Illuminate\\Routing\\Middleware\\ThrottleRequests->handleRequestUsingNamedLimiter(Object(Illuminate\\Http\\Request), Object(Closure), 'external-api', Object(Closure))
#31 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Routing\\Middleware\\ThrottleRequests->handle(Object(Illuminate\\Http\\Request), Object(Closure), 'external-api')
#32 /var/www/vendor/acme-packages/laravel-api/src/Middlewares/VerifyApiKeyAccess.php(63): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#33 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Acme\\Api\\Middlewares\\VerifyApiKeyAccess->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#34 /var/www/app/Http/Middleware/SentryContext.php(26): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#35 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\SentryContext->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#36 /var/www/app/Http/Middleware/ApiLanguage.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#37 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\ApiLanguage->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#38 /var/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#39 /var/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest(Object(Illuminate\\Http\\Request), Object(Illuminate\\Session\\Store), Object(Closure))
#40 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Session\\Middleware\\StartSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#41 /var/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#42 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#43 /var/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#44 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#45 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#46 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(723): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#47 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(698): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
#48 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(662): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
#49 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(651): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
#50 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(167): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
#51 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
#52 /var/www/vendor/barryvdh/laravel-debugbar/src/Middleware/InjectDebugbar.php(66): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#53 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Barryvdh\\Debugbar\\Middleware\\InjectDebugbar->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#54 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#55 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#56 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#57 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#58 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#59 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#60 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#61 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#62 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#63 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#64 /var/www/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#65 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fideloper\\Proxy\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#66 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#67 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(142): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#68 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(111): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#69 /var/www/public/index.php(54): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
Edit: Fixed code snippet @ali-amini
I believe I found the issue.
When trying to use messages, it first checks if there is a translation available with the message key data.required
.
However, there was a custom translation existing called data.mounted_serial
in resources/lang/en/validation.php
(referred here in the laravel doc)
// resources/lang/en/validation.php
return [
'attributes' => [
'data.mounted_serial' => 'Mounted serial',
],
];
I believe it was looking to it as an array because of the existing entry
'data' => [
'mounted_serial' => 'Mounted serial',
'required' => 'error.action.required.data',
]
By removing the existing translation entry data.mounted_serial
, the validation works properly with the given message in messages()