symfony/http-kernel · error · InvalidArgumentException
" ::resolve()" must yield at most one value for…
Error message
"%s::resolve()" must yield at most one value for non-variadic arguments.
What it means
ArgumentResolver::getArguments() counts how many values a non-pinned value resolver yields per argument and throws InvalidArgumentException when a resolver's resolve() generator yields more than one value for a non-variadic controller argument. Resolvers are generators precisely so they can signal 'near miss' by yielding nothing; multiple yields are only valid for variadic arguments.
Solutions
- Change the resolver to yield at most one value for non-variadic arguments; return/yield nothing to signal a near miss.
- If multiple values are legitimate, declare the controller argument variadic (e.g. Foo ...$foos).
- Aggregate candidates internally and pick one before yielding.
Example fix
// before
public function resolve(Request $request, ArgumentMetadata $argument): \Generator
{
foreach ($candidates as $c) {
yield $c; // throws when >1 and argument not variadic
}
}
// after
public function resolve(Request $request, ArgumentMetadata $argument): \Generator
{
if ($candidate = $this->pickBest($candidates)) {
yield $candidate;
}
} Defensive patterns
Strategy: validation
Validate before calling
// In your custom resolver:
$count = 0;
foreach ($this->doResolve($request, $argument) as $v) { if (++$count > 1 && !$argument->isVariadic()) { throw new \AssertionError('Resolver yielded multiple values'); } } Try / catch
try { $args = $argumentResolver->getArguments($request, $callable); } catch (\InvalidArgumentException $e) { /* check resolver generator yields */ } Prevention
- Yield at most one value in resolve(); yield nothing to decline
- Declare variadic arguments (...$x) when multiple values are valid
- Write unit tests that run resolvers against representative requests
When it happens
Trigger: A custom ValueResolverInterface::resolve() implemented with yield emits two or more values while the target controller argument is not declared variadic (...$args).
Common situations: Custom resolvers written to 'try' multiple candidate values with multiple yields; adapting old ArgumentValueResolverInterface code that returned arrays with several items; typos where a loop yields per-item instead of returning one.
Related errors
- You can only pin one resolver per argument, but argument "$
- Controller " " requires the "$ " argument that could not be…
- 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/c190e0ef38eaf859.
Report an issue: GitHub.
Appendix: source
Thrown at Controller/ArgumentResolver.php:115
$valueResolverExceptions = [];
foreach ($argumentValueResolvers as $name => $resolver) {
if (isset($disabledResolvers[\is_int($name) ? $resolver::class : $name])) {
continue;
}
try {
$count = 0;
foreach ($resolver->resolve($request, $metadata) as $argument) {
++$count;
$arguments[] = $argument;
}
} catch (NearMissValueResolverException $e) {
$valueResolverExceptions[] = $e;
}
if (1 < $count && !$metadata->isVariadic()) {
throw new \InvalidArgumentException(\sprintf('"%s::resolve()" must yield at most one value for non-variadic arguments.', get_debug_type($resolver)));
}
if ($count) {
// 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;View on GitHub (pinned to aa3a39d728)