{"record":{"id":"f0f33f854c42dae2","repo":"binary-husky/gpt_academic","slug":"json-f0f33f","errorCode":null,"errorMessage":"Json解析不合常规","messagePattern":"Json解析不合常规","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"request_llms/bridge_claude.py","lineNumber":138,"sourceCode":"                    # logger.info(f'[response] {result}')\n                    break\n                else:\n                    if chunkjson and chunkjson['type'] == 'content_block_delta':\n                        result += chunkjson['delta']['text']\n                        if observe_window is not None:\n                            # 观测窗，把已经获取的数据显示出去\n                            if len(observe_window) >= 1:\n                                observe_window[0] += chunkjson['delta']['text']\n                            # 看门狗，如果超过期限没有喂狗，则终止\n                            if len(observe_window) >= 2:\n                                if (time.time()-observe_window[1]) > watch_dog_patience:\n                                    raise RuntimeError(\"用户取消了程序。\")\n            except Exception as e:\n                chunk = get_full_error(chunk, stream_response)\n                chunk_decoded = chunk.decode()\n                error_msg = chunk_decoded\n                logger.error(error_msg)\n                raise RuntimeError(\"Json解析不合常规\")\n\n    return result\n\ndef make_media_input(history,inputs,image_paths):\n    for image_path in image_paths:\n        inputs = inputs + f'<br/><br/><div align=\"center\"><img src=\"file={os.path.abspath(image_path)}\"></div>'\n    return inputs\n\ndef predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_prompt='', stream = True, additional_fn=None):\n    \"\"\"\n    发送至chatGPT，流式获取输出。\n    用于基础的对话功能。\n    inputs 是本次问询的输入\n    top_p, temperature是chatGPT的内部调优参数\n    history 是之前的对话列表（注意无论是inputs还是history，内容太长了都会触发token数量溢出的错误）\n    chatbot 为WebUI中显示的对话列表，修改它，然后yield出去，可以直接修改对话界面内容\n    additional_fn代表点击的哪个按钮，按钮见functional.py\n    \"\"\"","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/request_llms/bridge_claude.py#L120-L156","documentation":"RuntimeError ('Json解析不合常规') from the except branch of the streaming loop in Claude predict_no_ui_long_connection. Any exception while iterating/decoding the SSE stream (JSONDecodeError from a malformed event, connection drop mid-frame, AttributeError when a chunk lacks expected keys) lands here; the handler pulls the raw error bytes via get_full_error, logs them, and re-raises with this generic message. So the message means 'the Anthropic event stream broke in a way that is not a clean watchdog cancel', with the real cause in the log.","triggerScenarios":"Anthropic API returns an error event or HTML body mid-stream; proxy cuts the connection and a partial SSE frame fails json.loads; chunkjson structure deviates (missing 'type' or 'delta') causing a KeyError inside the try; rate-limit payload returned as non-JSON after the response object was already obtained.","commonSituations":"Unstable proxies to api.anthropic.com; hitting Anthropic rate limits (429 bodies interleaved into the stream); very long generations dropped by intermediary proxies; API version changes altering event schemas the parser expects.","solutions":["Check the logged error_msg (logger.error prints the raw chunk) — it distinguishes rate limit, auth, and truncation causes.","Fix/verify the proxy: ANTHROPIC endpoint must be reachable and must not truncate SSE frames; try disabling proxies for api.anthropic.com.","On 429 rate limits, slow down request frequency or upgrade your Anthropic plan tier.","Update gpt_academic — newer bridge_claude.py versions harden the event parsing for schema changes."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    result = predict_no_ui_long_connection(inputs, llm_kwargs, history, sys_prompt, observe_window)\nexcept RuntimeError as e:\n    if 'Json解析不合常规' in str(e):\n        check_logged_raw_chunk()      # real cause is in logger.error output\n        if was_rate_limit_or_transient():\n            time.sleep(backoff); retry_request()\n        else:\n            raise","preventionTips":["Enable INFO/ERROR logging so the raw failing chunk is always captured.","Keep proxies stable for api.anthropic.com; SSE-unfriendly proxies are the top cause.","Respect Anthropic rate limits client-side to keep 429 bodies out of the stream.","Retry once on transient frame corruption before surfacing the error to users."],"tags":["claude","anthropic","json","streaming","network"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}