{"record":{"id":"41a82acf702614e1","repo":"xtekky/gpt4free","slug":"response-resp-json","errorCode":null,"errorMessage":"Response: {resp_json}","messagePattern":"Response: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"g4f/Provider/Qwen.py","lineNumber":665,"sourceCode":"                        msg_payload[\"size\"] = aspect_ratio\r\n\r\n                    async with session.post(\r\n                        f\"{cls.url}/api/v2/chat/completions?chat_id={conversation.chat_id}\",\r\n                        json=msg_payload,\r\n                        headers=req_headers,\r\n                        proxy=proxy,\r\n                        timeout=timeout,\r\n                        cookies=conversation.cookies,\r\n                    ) as resp:\r\n                        await cls.raise_for_status(resp)\r\n                        if resp.headers.get(\"content-type\", \"\").startswith(\r\n                            \"application/json\"\r\n                        ):\r\n                            resp_json = await resp.json()\r\n                            if resp_json.get(\"success\") is False or resp_json.get(\r\n                                \"data\", {}\r\n                            ).get(\"code\"):\r\n                                raise RuntimeError(f\"Response: {resp_json}\")\r\n                            else:\r\n                                # cant stream resp after `resp_json = await resp.json()`, so it stick\r\n                                raise RuntimeError(f\"Response: {resp_json}\")\r\n                        # args[\"cookies\"] = merge_cookies(args.get(\"cookies\"), resp)\r\n                        thinking_started = False\r\n                        usage = None\r\n                        async for chunk in sse_stream(resp):\r\n                            try:\r\n                                if \"response.created\" in chunk:\r\n                                    conversation.parent_id = chunk.get(\r\n                                        \"response.created\", {}\r\n                                    ).get(\"response_id\")\r\n                                    yield conversation\r\n                                error = chunk.get(\"error\", {})\r\n                                if error:\r\n                                    raise ResponseError(\r\n                                        f'{error[\"code\"]}: {error[\"details\"]}'\r\n                                    )\r","sourceCodeStart":647,"sourceCodeEnd":683,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f/Provider/Qwen.py#L647-L683","documentation":"Raised when Qwen's completion endpoint (POST /api/v2/chat/completions) answers with content-type application/json instead of an SSE stream AND the JSON indicates failure (success=false or a data.code error). Qwen returns JSON only for refusals (rate limits, model restrictions, moderation), so any JSON response is treated as an error; this branch is the explicit failure case.","triggerScenarios":"Sending a completion when the API refuses before streaming: free-tier rate limit on the model (data.code like 'RateLimited'), model not allowed for anonymous users, or prompt flagged by moderation.","commonSituations":"Using restricted models (e.g. some image/thinking models) anonymously; bursts of completions after new-chat creation; retry loop already burned midtoken on prior 429s; g4f behind Qwen API changes.","solutions":["Read the embedded resp_json — data.code names the refusal (rate limit vs model restriction).","For rate limits: wait and retry later; the inner loop already retries 5 times with 2s sleeps, longer waits are needed for hard limits.","Switch to an allowed default model.","Update g4f for current model gating."],"exampleFix":"# before\nr = await Qwen.create_async_generator(model='qwen3-image-preview', msgs)\n\n# after - fall back to default text model on refusal\ntry:\n    r = await Qwen.create_async_generator(model='qwen3-image-preview', msgs)\nexcept RuntimeError as e:\n    r = await Qwen.create_async_generator(model=Qwen.default_model, msgs)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"def is_qwen_json_refusal(exc: Exception) -> bool:\n    \"\"\"True when Qwen answered JSON with an explicit failure code.\"\"\"\n    return isinstance(exc, RuntimeError) and str(exc).startswith('Response:') and 'success' in str(exc)","tryCatchPattern":"try:\n    r = await Qwen.create_async_generator(model, msgs)\nexcept RuntimeError as e:\n    msg = str(e)\n    if msg.startswith('Response:') and 'RateLimited' in msg:\n        await asyncio.sleep(300)\n        r = await Qwen.create_async_generator(model, msgs)\n    elif msg.startswith('Response:'):\n        r = await Qwen.create_async_generator(Qwen.default_model, msgs)  # model fallback\n    else:\n        raise","preventionTips":["Prefer allowed default models for anonymous access","Wait out quota windows on RateLimited codes","Parse the embedded resp_json to choose backoff vs fallback","Update g4f for model gating changes"],"tags":["qwen","rate-limit","json-response","moderation","model-access"],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}