{"record":{"id":"dc477a2bd293e08f","repo":"symfony/http-kernel","slug":"request-payload-contains-invalid-form-data","errorCode":null,"errorMessage":"Request payload contains invalid \"form\" data.","messagePattern":"Request payload contains invalid \"form\" data\\.","errorType":"http","errorClass":"BadRequestHttpException","httpStatus":400,"severity":"error","filePath":"Controller/ArgumentResolver/RequestPayloadValueResolver.php","lineNumber":280,"sourceCode":"\n        if (!$this->serializer instanceof DecoderInterface || !$this->serializer->supportsDecoding($format)) {\n            $format = Request::getStructuredSuffixFormat($request->headers->get('CONTENT_TYPE')) ?? $format;\n        }\n\n        $type = match (true) {\n            $argument->isVariadic() => ($attribute->type ?? $argument->getType()).'[]',\n            'array' === $argument->getType() && null !== $attribute->type => $attribute->type.'[]',\n            default => $argument->getType(),\n        };\n\n        if (\\is_array($data)) {\n            $data = $this->mergeParamsAndFiles($data, $request->files->all());\n\n            return $this->serializer->denormalize($data, $type, self::hasNonStringScalar($data) ? $format : 'csv', $attribute->serializationContext + self::CONTEXT_DENORMALIZE + ('form' === $format ? ['filter_bool' => true] : []));\n        }\n\n        if ('form' === $format) {\n            throw new BadRequestHttpException('Request payload contains invalid \"form\" data.');\n        }\n\n        try {\n            return $this->serializer->deserialize($data, $type, $format, self::CONTEXT_DESERIALIZE + $attribute->serializationContext);\n        } catch (UnsupportedFormatException $e) {\n            throw new UnsupportedMediaTypeHttpException(\\sprintf('Unsupported format: \"%s\".', $format), $e);\n        } catch (NotEncodableValueException $e) {\n            throw new BadRequestHttpException(\\sprintf('Request payload contains invalid \"%s\" data.', $format), $e);\n        } catch (UnexpectedPropertyException $e) {\n            throw new BadRequestHttpException(\\sprintf('Request payload contains invalid \"%s\" property.', $e->property), $e);\n        }\n    }\n\n    private function mapUploadedFile(Request $request, ArgumentMetadata $argument, MapUploadedFile $attribute): UploadedFile|array|null\n    {\n        if ($files = $request->files->get($attribute->name ?? $argument->getName())) {\n            return !\\is_array($files) && $argument->isVariadic() ? [$files] : $files;\n        }","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/symfony/http-kernel/blob/aa3a39d7286a62cdfea98f0e69c651a3da6e36cf/Controller/ArgumentResolver/RequestPayloadValueResolver.php#L262-L298","documentation":"Symfony's #[MapRequestPayload] argument resolver throws this BadRequestHttpException when the request body format is 'form' (form-encoded) but the payload could not be normalized into data suitable for denormalization into the controller argument type. Form data cannot be used to populate the given typed object, so the request is rejected as a 400. It signals the submitted form body does not match what the mapped type expects.","triggerScenarios":"Using #[MapRequestPayload] on a controller argument whose request Content-Type is application/x-www-form-urlencoded (or multipart form data) where $data is not a string/array that can be denormalized - e.g. the request body failed to parse or the format was determined as 'form' while the data was null/scalar-invalid.","commonSituations":"POSTing an HTML form to an API endpoint typed for a JSON-style DTO; a client sending multipart/form-data without files while the endpoint expects a structured payload; mismatched Content-Type headers versus the typed controller signature.","solutions":["Send the payload as JSON (Content-Type: application/json) if the controller argument is a DTO, or change the endpoint to accept individual form fields instead of #[MapRequestPayload].","Verify the request actually contains form fields (check request->request->all()) and that the Content-Type header matches the body.","If form submission is intended, bind fields manually via $request->request->all() and a DTO constructor, or add a form Type instead of payload mapping.","Clear any proxy/middleware that strips or rewrites the Content-Type or body."],"exampleFix":"// before (client sends form-encoded body to a DTO endpoint)\ncurl -X POST /api/user -d 'name=John&email=j@x.com'\n// after (send JSON matching the mapped type)\ncurl -X POST /api/user -H 'Content-Type: application/json' -d '{\"name\":\"John\",\"email\":\"j@x.com\"}'","handlingStrategy":"validation","validationCode":"const ct = request.headers.get('Content-Type') ?? '';\nif (!ct.includes('application/json')) {\n  throw new Error('Send application/json for DTO endpoints');\n}\nJSON.parse(rawBody); // throws early if body is not valid JSON","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Match Content-Type to the controller argument mapping (JSON for #[MapRequestPayload] DTOs).","Send form data only to controllers that read request->request directly or use Form types.","Document each endpoint's accepted media types and enforce them client-side."],"tags":["symfony","http-kernel","request-payload","bad-request"],"backgroundTag":"schema-validation-failed","analyzedSha":"aa3a39d7286a62cdfea98f0e69c651a3da6e36cf","analyzedAt":"2026-09-13T18:03:36.509Z","contentChangedAt":"2026-09-13T18:03:36.509Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}