infiniflow/ragflow · warning · TypeError
Request body is not a valid form payload.
Error message
Request body is not a valid form payload.
What it means
Raised by _coerce_request_data when the request has a body with a non-JSON content type but await request.form yields no parseable form fields. The parser falls back to form data; when that is also empty/unparseable, the body is rejected as an invalid form payload.
Source
Thrown at api/utils/api_utils.py:86
has_body = bool(body_bytes)
content_type = (request.content_type or "").lower()
is_json = content_type.startswith("application/json")
if not has_body:
payload = {}
elif is_json:
payload = await request.get_json(force=False, silent=False)
if isinstance(payload, dict):
payload = payload or {}
elif isinstance(payload, str):
raise AttributeError("'str' object has no attribute 'get'")
else:
raise TypeError("JSON payload must be an object.")
else:
form = await request.form
payload = form.to_dict() if form else None
if payload is None:
raise TypeError("Request body is not a valid form payload.")
request._cached_payload = payload
return payload
async def get_request_json():
return await _coerce_request_data()
def serialize_for_json(obj):
"""
Recursively serialize objects to make them JSON serializable.
Handles ModelMetaclass and other non-serializable objects.
"""
if hasattr(obj, "__dict__"):
# For objects with __dict__, try to serialize their attributes
try:
return {key: serialize_for_json(value) for key, value in obj.__dict__.items() if not key.startswith("_")}View on GitHub (pinned to 554fb1133a)
Solutions
- Set Content-Type: application/json and send a JSON object for these endpoints.
- For uploads, use proper multipart/form-data with a boundary (requests files=/data= does this correctly).
- Remove stray Content-Type headers on empty-body requests.
- Verify intermediate proxies do not rewrite the content type.
Example fix
# before
requests.post(url, data=payload_str, headers={'Content-Type': 'text/plain'})
# after
requests.post(url, json=payload_obj) Defensive patterns
Strategy: validation
Validate before calling
if body and content_type not in ('application/json', 'application/x-www-form-urlencoded', 'multipart/form-data'):
return json_error_response('unsupported content type', 415) Type guard
ALLOWED = ('application/json', 'application/x-www-form-urlencoded', 'multipart/form-data')
def is_supported_content_type(ct: str | None) -> bool:
return (ct or '').split(';')[0].strip().lower() in ALLOWED or not body Try / catch
try:
data = await get_request_json()
except TypeError:
return json_error_response('send JSON object or valid form fields', 400) Prevention
- Always set an explicit, correct Content-Type header.
- Use HTTP libraries' built-in form/json helpers so boundaries and headers are well-formed.
- Audit proxies/gateways that rewrite Content-Type.
When it happens
Trigger: Sending a body with Content-Type: text/plain, application/octet-stream, or a malformed multipart/urlencoded body (bad boundary, empty multipart) to an endpoint that reads the payload via get_request_json.
Common situations: curl -d with default content type not matching what was intended; broken multipart boundaries from hand-rolled clients; proxies stripping or rewriting content-type; empty bodies with a non-JSON content type set.
Related errors
- 'str' object has no attribute 'get'
- JSON payload must be an object.
- Jira validation failed: {message}
- main() must be defined or exported.
- main() must return a value. Use null for an empty result.
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/8e385675525146b9.
Report an issue: GitHub.