{"record":{"id":"5bf0dd29a2e094ec","repo":"xtekky/gpt4free","slug":"failed-to-read-response-chunk-decode-errors-rep","errorCode":null,"errorMessage":"Failed to read response: {chunk.decode(errors='replace')}","messagePattern":"Failed to read response: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"g4f/Provider/hf_space/CohereForAI_C4AI_Command.py","lineNumber":161,"sourceCode":"                        \"is_retry\": False,\n                        \"is_continue\": False,\n                        \"web_search\": False,\n                        \"tools\": [],\n                    }\n                ),\n                content_type=\"application/json\",\n            )\n            async with session.post(\n                f\"{cls.conversation_url}/{conversation.conversationId}\",\n                data=data,\n                proxy=proxy,\n            ) as response:\n                await raise_for_status(response)\n                async for chunk in response.content:\n                    try:\n                        data = json.loads(chunk)\n                    except json.JSONDecodeError as e:\n                        raise RuntimeError(\n                            f\"Failed to read response: {chunk.decode(errors='replace')}\",\n                            e,\n                        )\n                    if data[\"type\"] == \"stream\":\n                        yield data[\"token\"].replace(\"\\u0000\", \"\")\n                    elif data[\"type\"] == \"title\":\n                        yield TitleGeneration(data[\"title\"])\n                    elif data[\"type\"] == \"finalAnswer\":\n                        break\n","sourceCodeStart":143,"sourceCodeEnd":171,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f/Provider/hf_space/CohereForAI_C4AI_Command.py#L143-L171","documentation":"Raised in the Cohere Command HF Space provider while reading the streamed NDJSON response: response.content is iterated as raw bytes and each chunk is fed directly to json.loads. aiohttp yields chunks at network-buffer boundaries, not line boundaries, so a chunk can contain half a JSON object, multiple objects, or trailing partial data — any of which makes json.loads raise JSONDecodeError. The raw chunk is included in the message for diagnosis.","triggerScenarios":"Any stream where an NDJSON line crosses a TCP/TLS buffer boundary (essentially every non-trivial response — the bug fires intermittently whenever a token line is split across reads); responses where the server sends multiple small JSON objects in one read; error pages/HTML injected mid-stream.","commonSituations":"Long generations on the cohere-for-ai-c4ai-command Space failing partway through with this error; the same code working for short replies (single small chunk) but failing for long ones — a classic symptom of missing line buffering.","solutions":["Buffer reads until newline before parsing: iterate with readline() (response.content is an aiohttp StreamReader) or accumulate a bytes buffer and split on b'\\n'.","If it fires on the very first chunk, check the chunk text in the message for an HTML error/Cloudflare page — then the fix is the Space being up / cookies, not parsing.","Retry the request: boundary-split failures are intermittent, but the correct fix is line-buffered parsing."],"exampleFix":"# before\nasync for chunk in response.content:\n    try:\n        data = json.loads(chunk)\n    except json.JSONDecodeError as e:\n        raise RuntimeError(f\"Failed to read response: {chunk.decode(errors='replace')}\", e)\n\n# after (line-buffered NDJSON parsing)\nbuffer = b\"\"\nasync for chunk in response.content:\n    buffer += chunk\n    while b\"\\n\" in buffer:\n        line, buffer = buffer.split(b\"\\n\", 1)\n        if not line.strip():\n            continue\n        data = json.loads(line)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    ...\nexcept RuntimeError as e:\n    if 'Failed to read response' in str(e):\n        await asyncio.sleep(1)  # chunk-boundary flakes: single retry usually succeeds\n        ...","preventionTips":["When patching, switch to line-buffered NDJSON parsing (readline/split on newline) — the root fix.","Keep streams short or resume conversations to reduce exposure to boundary splits.","Watch upstream g4f fixes for the Cohere Space reader."],"tags":["hf-space","json","streaming","ndjson","parser-bug"],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}