symfony/http-kernel · error · LogicException

Could not resolve the "$

Error message

Could not resolve the "$%s" controller argument: argument should be typed.

What it means

During onKernelControllerArguments, if the mapped controller argument has no type declaration, Symfony cannot instantiate or validate a payload for it and throws this LogicException. Every argument resolved via MapQueryString/MapRequestPayload must have a class or type declaration.

Solutions

  1. Add a class or built-in type declaration to the annotated argument
  2. Remove the payload attribute if the argument is not meant to be mapped
  3. Use a DTO class as the argument type

Example fix

// before
public function index(#[MapQueryString] $filter) {}
// after
public function index(#[MapQueryString] SearchFilter $filter) {}
Defensive patterns

Strategy: type-guard

Validate before calling

foreach ($annotatedParams as $p) { if (!$p->getType()) { throw new \TypeError("{$p->name} needs a type for payload mapping"); } }

Type guard

if ($param->getType() instanceof \ReflectionNamedType && !$param->getType()->isBuiltin() || $param->getType()?->isBuiltin()) { /* typed */ }

Try / catch

try { $response = $kernel->handle($request); } catch (\LogicException $e) { if (str_contains($e->getMessage(), 'argument should be typed')) { /* add type hint */ } throw $e; }

Prevention

When it happens

Trigger: A controller argument annotated with #[MapQueryString] or #[MapRequestPayload] that has no type hint (e.g. function index($payload)) — exercised by tests like testNotTypedArgument and testDefaultValueArgument.

Common situations: Refactoring away a type hint, copy-pasting an attribute onto an untyped argument, or relying on docblock types which the resolver ignores.

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


AI-assisted analysis of symfony/http-kernel@aa3a39d728 (2026-09-13). Data as JSON: /api/errors/802cebcbc5e2c7dd. Report an issue: GitHub.

Appendix: source

Thrown at Controller/ArgumentResolver/RequestPayloadValueResolver.php:129

        $arguments = $event->getArguments();

        foreach ($arguments as $i => $argument) {
            if ($argument instanceof MapQueryString) {
                $payloadMapper = $this->mapQueryString(...);
                $validationFailedCode = $argument->validationFailedStatusCode;
            } elseif ($argument instanceof MapRequestPayload) {
                $payloadMapper = $this->mapRequestPayload(...);
                $validationFailedCode = $argument->validationFailedStatusCode;
            } elseif ($argument instanceof MapUploadedFile) {
                $payloadMapper = $this->mapUploadedFile(...);
                $validationFailedCode = $argument->validationFailedStatusCode;
            } else {
                continue;
            }
            $request = $event->getRequest();

            if (!$argument->metadata->getType()) {
                throw new \LogicException(\sprintf('Could not resolve the "$%s" controller argument: argument should be typed.', $argument->metadata->getName()));
            }

            if ($this->validator) {
                $violations = new ConstraintViolationList();
                try {
                    $payload = $payloadMapper($request, $argument->metadata, $argument);
                } catch (PartialDenormalizationException $e) {
                    $trans = $this->translator ? $this->translator->trans(...) : static fn ($m, $p) => strtr($m, $p);
                    $errors = method_exists($e, 'getNotNormalizableValueErrors') ? $e->getNotNormalizableValueErrors() : $e->getErrors();
                    foreach ($errors as $error) {
                        $parameters = [];
                        $template = 'This value was of an unexpected type.';
                        if ($expectedTypes = $error->getExpectedTypes()) {
                            $template = 'This value should be of type {{ type }}.';
                            $parameters['{{ type }}'] = implode('|', $expectedTypes);
                        }
                        if ($error->canUseMessageForUser()) {
                            $parameters['hint'] = $error->getMessage();

View on GitHub (pinned to aa3a39d728)