symfony/http-kernel · error · RuntimeException
Controller " " requires the "$ " argument that could not be…
Error message
Controller "%s" requires the "$%s" argument that could not be resolved. Possible reasons: %s
What it means
ArgumentResolver::getArguments() throws RuntimeException when no value resolver could resolve a required controller argument. The message aggregates numbered 'possible reasons' collected from resolvers that came close (NearMissValueResolverException) to help diagnose why resolution failed.
Solutions
- Read the numbered 'possible reasons' in the message — they point at which resolvers almost matched and why they declined.
- Annotate the argument with the appropriate attribute (#[(Map)QueryString/RequestPayload/File/User]) or give it a default/null-able type.
- Ensure the argument type is class/enum-based and a matching resolver service is registered and tagged (argument.value_resolver).
- If the value should come from the route, add it to the route requirements/defaults or fetch it from Request inside the controller.
Example fix
// before
public function edit(Request $request, ProductDto $dto) {}
// after
public function edit(#[MapRequestPayload] ProductDto $dto) {} Defensive patterns
Strategy: try-catch
Validate before calling
foreach ((new \ReflectionMethod($controller, '__invoke'))->getParameters() as $p) {
if (!$p->getType() instanceof \ReflectionNamedType && !$p->isDefaultValueAvailable() && !$p->allowsNull()) {
// ensure an attribute or resolver exists
}
} Try / catch
try { $response = $controller(...$args); } catch (\RuntimeException $e) { if (str_contains($e->getMessage(), 'could not be resolved')) { /* add attribute/default or provide the argument */ } throw $e; } Prevention
- Annotate DTO/value-object arguments with the matching #[Map*] attribute
- Read the numbered 'possible reasons' — they name the failing resolvers
- Keep resolver services tagged argument.value_resolver and registered in the current env
- Avoid untyped or scalar arguments without defaults in controllers
When it happens
Trigger: Invoking a controller whose argument has no default value, is not nullable, and for which no registered resolver yields a value — e.g. an untyped/scalar argument without #[MapRequestPayload]-style attributes, a service argument not autowired, or the required request attribute/query parameter absent.
Common situations: Forgetting #[MapRequestPayload]/#[CurrentUser] attributes on typed value objects; scalar controller arguments without defaults (works only in certain legacy configurations); calling the controller programmatically without providing the argument; route not passing a required {_format}/attribute; missing bundles that provided resolvers.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- You can only pin one resolver per argument, but argument "$
- " ::resolve()" must yield at most one value for…
- Could not resolve the argument typed
- #[MapQueryParameter] cannot be used on controller argument
- Could not resolve the "$
AI-assisted analysis of symfony/http-kernel@aa3a39d728 (2026-09-13).
Data as JSON: /api/errors/93b91df1319afac0.
Report an issue: GitHub.
Appendix: source
Thrown at Controller/ArgumentResolver.php:137
// continue to the next controller argument
continue 2;
}
}
$reasons = array_map(static fn (NearMissValueResolverException $e) => $e->getMessage(), $valueResolverExceptions);
if (!$reasons) {
$reasons[] = 'Either the argument is nullable and no null value has been provided, no default value has been provided or there is a non-optional argument after this one.';
}
$reasonCounter = 1;
if (\count($reasons) > 1) {
foreach ($reasons as $i => $reason) {
$reasons[$i] = $reasonCounter.') '.$reason;
++$reasonCounter;
}
}
throw new \RuntimeException(\sprintf('Controller "%s" requires the "$%s" argument that could not be resolved. '.($reasonCounter > 1 ? 'Possible reasons: ' : '').'%s', $metadata->getControllerName(), $metadata->getName(), implode(' ', $reasons)));
}
return $arguments;
}
/**
* @return iterable<int, ValueResolverInterface>
*/
public static function getDefaultArgumentValueResolvers(): iterable
{
return [
new RequestAttributeValueResolver(),
new RequestValueResolver(),
new SessionValueResolver(),
new DefaultValueResolver(),
new VariadicValueResolver(),
];
}View on GitHub (pinned to aa3a39d728)