infiniflow/ragflow · warning · AttributeError

'str' object has no attribute 'get'

Error message

'str' object has no attribute 'get'

What it means

Raised by _coerce_request_data in api_utils when a JSON body parses to a bare string (e.g. the literal body "\"hello\"" or a quoted token). RAGFlow request handlers expect a JSON object mapping to kwargs; scalar JSON values are rejected with this AttributeError before reaching the handler.

Source

Thrown at api/utils/api_utils.py:79

async def _coerce_request_data() -> dict:
    """Fetch JSON body with sane defaults; fallback to form data."""
    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):
    """

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Send a JSON object as the body: {"key": "value"} with Content-Type: application/json.
  2. Remove double serialization in the client: call json.dumps (or the requests json= parameter) exactly once.
  3. Validate the payload shape client-side before sending.

Example fix

# before
requests.post(url, data=json.dumps(json.dumps(payload)))  # double-encoded string

# after
requests.post(url, json=payload)  # sends an object once
Defensive patterns

Strategy: type-guard

Validate before calling

body = payload if isinstance(payload, dict) else {'value': payload}  # client side: always send an object

Type guard

def is_json_object_body(payload) -> bool:
    return isinstance(payload, dict)

Try / catch

try:
    data = await get_request_json()
except AttributeError:
    return json_error_response('JSON body must be an object, not a string', 400)

Prevention

When it happens

Trigger: POSTing with Content-Type: application/json a body that is a JSON string rather than an object: '"text"', a bare JWT, or a double-encoded payload ('\"{\\\"a\\\":1}\"').

Common situations: Clients double-serializing JSON (json.dumps twice); pasting a raw token as the body; curl -d '"hello"' without realizing the endpoint needs an object.

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/0da49db34cc1a55a. Report an issue: GitHub.