{"id":"94b1e6047b5c8990","repo":"tiangolo/fastapi","slug":"invalid-yaml","errorCode":null,"errorMessage":"Invalid YAML","messagePattern":"Invalid YAML","errorType":"http","errorClass":"HTTPException","httpStatus":422,"severity":"error","filePath":"docs_src/path_operation_advanced_configuration/tutorial007_py310.py","lineNumber":27,"sourceCode":"    name: str\n    tags: list[str]\n\n\n@app.post(\n    \"/items/\",\n    openapi_extra={\n        \"requestBody\": {\n            \"content\": {\"application/x-yaml\": {\"schema\": Item.model_json_schema()}},\n            \"required\": True,\n        },\n    },\n)\nasync def create_item(request: Request):\n    raw_body = await request.body()\n    try:\n        data = yaml.safe_load(raw_body)\n    except yaml.YAMLError:\n        raise HTTPException(status_code=422, detail=\"Invalid YAML\")\n    try:\n        item = Item.model_validate(data)\n    except ValidationError as e:\n        raise HTTPException(status_code=422, detail=e.errors(include_url=False))\n    return item\n","sourceCodeStart":9,"sourceCodeEnd":33,"githubUrl":"https://github.com/tiangolo/fastapi/blob/42a41db11f6882807ac3c057b942178d53b97438/docs_src/path_operation_advanced_configuration/tutorial007_py310.py#L9-L33","documentation":"FastAPI returns HTTP 422 \"Invalid YAML\" when `yaml.safe_load(raw_body)` raises a `yaml.YAMLError` while parsing the request body declared (via openapi_extra) as application/x-yaml. The endpoint reads the raw body manually because FastAPI does not natively bind YAML bodies, then validates the parsed dict against the Item Pydantic model. This 422 specifically denotes a YAML syntax failure distinct from the subsequent Pydantic validation 422.","triggerScenarios":"POST /items/ with Content-Type: application/x-yaml and a body that is not well-formed YAML (e.g. unbalanced indentation, bad mapping syntax, tabs where spaces are required).","commonSituations":"Clients sending JSON to a YAML-only endpoint; copy/paste introducing tabs; encodings/BOM; CI generating YAML with a faulty template; version drift in the YAML library producing stricter parsing.","solutions":["Validate the body with a local YAML parser (e.g. `yaml.safe_load`) before sending.","Ensure Content-Type is application/x-yaml and the body uses spaces, not tabs.","Differentiate this 422 from the Pydantic-validation 422 in client error handling by inspecting detail text.","Return a more descriptive detail (e.g. include the parser's line number) to aid debugging."],"exampleFix":"# before\ntry:\n    data = yaml.safe_load(raw_body)\nexcept yaml.YAMLError:\n    raise HTTPException(status_code=422, detail=\"Invalid YAML\")\n\n# after\ntry:\n    data = yaml.safe_load(raw_body)\nexcept yaml.YAMLError as e:\n    raise HTTPException(status_code=422, detail=f\"Invalid YAML: {e}\")","handlingStrategy":"validation","validationCode":"import yaml\nbody_text = open(\"payload.yaml\").read()\ntry:\n    yaml.safe_load(body_text)\nexcept yaml.YAMLError as e:\n    raise ValueError(f\"body is not valid YAML: {e}\")\nclient.post(\"/items/\", content=body_text, headers={\"Content-Type\": \"application/x-yaml\"})","typeGuard":"def is_valid_yaml(text: str) -> bool:\n    try:\n        yaml.safe_load(text)\n        return True\n    except yaml.YAMLError:\n        return False","tryCatchPattern":"r = client.post(\"/items/\", content=body, headers={\"Content-Type\": \"application/x-yaml\"})\nif r.status_code == 422 and \"Invalid YAML\" in r.text:\n    # distinguish YAML-parse 422 from Pydantic-validation 422\n    ...","preventionTips":["Lint YAML locally before sending.","Use spaces, never tabs, in indentation.","Set Content-Type to application/x-yaml explicitly.","Differentiate parse-422 from schema-422 in client error handling."],"tags":["fastapi","yaml","http-422","validation","request-body","openapi-extra"],"analyzedSha":"42a41db11f6882807ac3c057b942178d53b97438","analyzedAt":"2026-08-04T19:23:32.007Z","schemaVersion":2}