Skip to content

#[MapRequestPayload] does not work if a DTO contains **only** nested DTOs #50708

@someniatko

Description

@someniatko

Symfony version(s) affected

6.3.0+

Description

If you use #MapRequestPayload attribute on a DTO whose only field is a nested DTO, Symfony crashes on the container compilation stage.

How to reproduce

(Also see https://github.com/someniatko/symfony-50708-reproducer)

Consider a following situation:

class ParentDto
{
    public function __construct(public NestedDto $nested) {}
}

class NestedDto
{
    public function __construct(public string $value) {}
}

class Controller extends AbstractController
{
    #[Route(path: [ '/path' ], methods: 'POST')]
    public function index(#[MapRequestPayload] ParentDto $dto): Response
    {
        return $this->json($dto);
    }
}

Then execute php bin/console cache:clear for any environment.

Expected: Cache clears successfully

Actual:

In DefinitionErrorExceptionPass.php line 51:
                                                                                                                                                                
  Cannot autowire service "App\Dto\NestedDto": argument "$value" of method "__construct()" is type-hinted "string", you should configure its value explicitly.

It took me almost four hours to pinpoint the issue, because I thought maybe some of the bundles I use are the culprit, or my config is incorrect, and also because, and it's the most "funny" part, this will work fine:

class ParentDto
{
    public function __construct(public string $additionalValue, public NestedDto $nested) {}
}

class NestedDto
{
    public function __construct(public string $value) {}
}

Possible Solution

No response

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions