{"record":{"id":"22c320f151fcb170","repo":"binary-husky/gpt_academic","slug":"dec-error-msg","errorCode":null,"errorMessage":"dec['error_msg']","messagePattern":"dec\\['error_msg'\\]","errorType":"exception","errorClass":"ConnectionAbortedError","httpStatus":null,"severity":"error","filePath":"request_llms/bridge_qianfan.py","lineNumber":118,"sourceCode":"        \"messages\": generate_message_payload(inputs, llm_kwargs, history, system_prompt),\n        \"stream\": True\n    })\n    headers = {\n        'Content-Type': 'application/json'\n    }\n    response = requests.request(\"POST\", url, headers=headers, data=payload, stream=True)\n    buffer = \"\"\n    for line in response.iter_lines():\n        if len(line) == 0: continue\n        try:\n            dec = line.decode().lstrip('data:')\n            dec = json.loads(dec)\n            incoming = dec['result']\n            buffer += incoming\n            yield buffer\n        except:\n            if ('error_code' in dec) and (\"max length\" in dec['error_msg']):\n                raise ConnectionAbortedError(dec['error_msg'])  # 上下文太长导致 token 溢出\n            elif ('error_code' in dec):\n                raise RuntimeError(dec['error_msg'])\n\n\ndef predict_no_ui_long_connection(inputs:str, llm_kwargs:dict, history:list=[], sys_prompt:str=\"\",\n                                  observe_window:list=[], console_silence:bool=False):\n    \"\"\"\n        ⭐多线程方法\n        函数的说明请见 request_llms/bridge_all.py\n    \"\"\"\n    watch_dog_patience = 5\n    response = \"\"\n\n    for response in generate_from_baidu_qianfan(inputs, llm_kwargs, history, sys_prompt):\n        if len(observe_window) >= 1:\n            observe_window[0] = response\n        if len(observe_window) >= 2:\n            if (time.time()-observe_window[1]) > watch_dog_patience: raise RuntimeError(\"程序终止。\")","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/request_llms/bridge_qianfan.py#L100-L136","documentation":"KeyError('error_msg') inside generate_from_baidu_qianfan's bare except: the try block failed (usually because dec['result'] is missing - Qianfan sent an error frame instead of a content frame), and the handler then evaluates dec['error_msg'] while 'error_code' IS in dec but 'error_msg' is not. The original stream error is masked by this secondary KeyError.","triggerScenarios":"Qianfan streaming an error object containing error_code but no error_msg field (schema variant or non-standard relay); a frame where dec itself is a partial/empty dict after lstrip('data:') mangling; dec unbound because line.decode() itself raised on the first iteration.","commonSituations":"Qianfan API version changes to its error-frame schema; expired/invalid access_token producing an error body without error_msg; hitting QPS limits with a differently-shaped error.","solutions":["Log dec inside the except block to see the actual error frame Qianfan returned","Use dec.get('error_msg') instead of dec['error_msg'] and raise a message including dec.get('error_code')","If error_code is 111 (token expired), clear the cached access token and re-authenticate","Check BAIDU_CLOUD_API_KEY/SECRET_KEY validity and Qianfan quota"],"exampleFix":"# before\nif ('error_code' in dec) and (\"max length\" in dec['error_msg']):\n    raise ConnectionAbortedError(dec['error_msg'])\nelif ('error_code' in dec):\n    raise RuntimeError(dec['error_msg'])\n\n# after\nif 'error_code' in dec:\n    msg = dec.get('error_msg') or str(dec)\n    if 'max length' in msg:\n        raise ConnectionAbortedError(msg)\n    raise RuntimeError(msg)","handlingStrategy":"try-catch","validationCode":"token = get_access_token()\nassert token and token != 'None', 'Qianfan access token invalid - check API/SECRET keys and account quota'","typeGuard":"def qianfan_frame_is_ok(dec: dict) -> bool:\n    return isinstance(dec, dict) and 'result' in dec","tryCatchPattern":"try:\n    for partial in generate_from_baidu_qianfan(inputs, llm_kwargs, history, sys_prompt):\n        buffer = partial\nexcept KeyError as e:\n    if e.args[0] == 'error_msg':\n        # original qianfan error frame lost - log raw lines and re-auth\n        logging.error('qianfan sent error frame without error_msg')\n        raise RuntimeError('qianfan stream error (schema missing error_msg)') from e\n    raise","preventionTips":["Patch the bridge to use dec.get('error_msg') so the real error_code survives","Verify the access token is fresh before long generations (code 111 = expired)","Log raw SSE lines when integrating a new provider version"],"tags":["qianfan","baidu","keyerror","error-handling","streaming"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}