infiniflow/ragflow · warning · TypeError
JSON payload must be an object.
Error message
JSON payload must be an object.
What it means
Raised by _coerce_request_data when a JSON body parses successfully but is not an object — arrays ([1,2]), numbers, booleans, or null. Handlers use .get() on the payload, so non-object JSON is rejected with TypeError at the parsing layer.
Source
Thrown at api/utils/api_utils.py:81
if hasattr(request, "_cached_payload"):
return request._cached_payload
payload: Any = None
body_bytes = await request.get_data()
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.View on GitHub (pinned to 554fb1133a)
Solutions
- Wrap list payloads in an object: send {"ids": [...]} instead of [...].
- Check the endpoint's documented request schema and match the top-level type.
- Add a client-side assertion that the serialized body starts with '{' for JSON endpoints.
Example fix
# before
requests.post(url, json=['doc1', 'doc2']) # array -> TypeError
# after
requests.post(url, json={'ids': ['doc1', 'doc2']}) Defensive patterns
Strategy: type-guard
Validate before calling
assert isinstance(payload, dict), 'top-level JSON must be an object'
Type guard
def is_json_object(payload) -> bool:
return isinstance(payload, dict) Try / catch
try:
data = await get_request_json()
except TypeError:
return json_error_response('JSON payload must be an object', 400) Prevention
- Wrap arrays inside objects ({"ids": [...]}) per the endpoint schema.
- Validate the top-level JSON type in client interceptors before sending.
When it happens
Trigger: POSTing a JSON array as the request body ('["a","b"]'), a bare number/true/null body, or an API client whose serializer emits a list where the endpoint expects an object like {"ids": [...]}.
Common situations: Clients wrapping batch payloads as bare arrays when the endpoint wants an object; copy-pasted example bodies from other APIs; null bodies sent explicitly.
Related errors
- 'str' object has no attribute 'get'
- Request body is not a valid form payload.
- flow.formatTypeError
- Tool arguments for {name} must be an object, got {type(argum
- Querit {name} must be an array of strings.
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/f0d199c063add28a.
Report an issue: GitHub.