{"record":{"id":"8c6223c1793049e9","repo":"headroomlabs-ai/headroom","slug":"body-too-large-status-env-must-be-a-4xx-5xx-stat","errorCode":null,"errorMessage":"{BODY_TOO_LARGE_STATUS_ENV} must be a 4xx/5xx status, got {value}","messagePattern":"(.+?) must be a 4xx/5xx status, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"headroom/proxy/request_limit_policy.py","lineNumber":34,"sourceCode":"    try:\n        value = int(raw)\n    except ValueError as exc:\n        raise ValueError(f\"{SSE_EVENT_MAX_BYTES_ENV} must be an integer, got {raw!r}\") from exc\n    if value <= 0:\n        raise ValueError(f\"{SSE_EVENT_MAX_BYTES_ENV} must be positive, got {value}\")\n    return value\n\n\ndef resolve_body_too_large_status(raw: str | None) -> int:\n    \"\"\"Resolve the HTTP status code for body-too-large rejections.\"\"\"\n    if raw is None or raw == \"\":\n        return BODY_TOO_LARGE_STATUS_DEFAULT\n    try:\n        value = int(raw)\n    except ValueError as exc:\n        raise ValueError(f\"{BODY_TOO_LARGE_STATUS_ENV} must be an integer, got {raw!r}\") from exc\n    if not 400 <= value < 600:\n        raise ValueError(f\"{BODY_TOO_LARGE_STATUS_ENV} must be a 4xx/5xx status, got {value}\")\n    return value\n","sourceCodeStart":16,"sourceCodeEnd":36,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/proxy/request_limit_policy.py#L16-L36","documentation":"resolve_body_too_large_status restricts the body-too-large rejection status to the 400-599 range, because it must be a real client/server error code the proxy returns. Codes like 200, 307, 399, 600, or negatives are rejected at startup.","triggerScenarios":"HEADROOM_PROXY_BODY_TOO_LARGE_STATUS set to 200, 301, 399, 600, or any value outside 400 <= value < 600.","commonSituations":"Using an informational/success code to 'pass through'; typos such as 41 or 4313; testing unusual status handling.","solutions":["Choose a 4xx or 5xx code, typically 413.","Unset the variable for the default.","Validate operator-supplied statuses against the 400-599 range before deploy."],"exampleFix":"# before\nexport HEADROOM_PROXY_BODY_TOO_LARGE_STATUS=200\n\n# after\nexport HEADROOM_PROXY_BODY_TOO_LARGE_STATUS=413","handlingStrategy":"validation","validationCode":"raw = os.environ.get(\"HEADROOM_PROXY_BODY_TOO_LARGE_STATUS\")\nif raw not in (None, \"\") and not 400 <= int(raw) < 600:\n    raise SystemExit(\"status must be 4xx/5xx\")","typeGuard":"def is_error_status(code: int) -> bool:\n    return 400 <= code < 600","tryCatchPattern":"try:\n    status = resolve_body_too_large_status(raw)\nexcept ValueError as e:\n    abort_with(e)","preventionTips":["Keep 413 unless an explicit 4xx/5xx is required.","Reject success/redirect codes in config review."],"tags":["env","validation","http"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}