binary-husky/gpt_academic · error · ConnectionAbortedError

dec['error_msg']

Error message

dec['error_msg']

What it means

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.

Source

Thrown at request_llms/bridge_qianfan.py:118

        "messages": generate_message_payload(inputs, llm_kwargs, history, system_prompt),
        "stream": True
    })
    headers = {
        'Content-Type': 'application/json'
    }
    response = requests.request("POST", url, headers=headers, data=payload, stream=True)
    buffer = ""
    for line in response.iter_lines():
        if len(line) == 0: continue
        try:
            dec = line.decode().lstrip('data:')
            dec = json.loads(dec)
            incoming = dec['result']
            buffer += incoming
            yield buffer
        except:
            if ('error_code' in dec) and ("max length" in dec['error_msg']):
                raise ConnectionAbortedError(dec['error_msg'])  # 上下文太长导致 token 溢出
            elif ('error_code' in dec):
                raise RuntimeError(dec['error_msg'])


def predict_no_ui_long_connection(inputs:str, llm_kwargs:dict, history:list=[], sys_prompt:str="",
                                  observe_window:list=[], console_silence:bool=False):
    """
        ⭐多线程方法
        函数的说明请见 request_llms/bridge_all.py
    """
    watch_dog_patience = 5
    response = ""

    for response in generate_from_baidu_qianfan(inputs, llm_kwargs, history, sys_prompt):
        if len(observe_window) >= 1:
            observe_window[0] = response
        if len(observe_window) >= 2:
            if (time.time()-observe_window[1]) > watch_dog_patience: raise RuntimeError("程序终止。")

View on GitHub (pinned to d6bde0fa54)

Solutions

  1. Log dec inside the except block to see the actual error frame Qianfan returned
  2. Use dec.get('error_msg') instead of dec['error_msg'] and raise a message including dec.get('error_code')
  3. If error_code is 111 (token expired), clear the cached access token and re-authenticate
  4. Check BAIDU_CLOUD_API_KEY/SECRET_KEY validity and Qianfan quota

Example fix

# before
if ('error_code' in dec) and ("max length" in dec['error_msg']):
    raise ConnectionAbortedError(dec['error_msg'])
elif ('error_code' in dec):
    raise RuntimeError(dec['error_msg'])

# after
if 'error_code' in dec:
    msg = dec.get('error_msg') or str(dec)
    if 'max length' in msg:
        raise ConnectionAbortedError(msg)
    raise RuntimeError(msg)
Defensive patterns

Strategy: try-catch

Validate before calling

token = get_access_token()
assert token and token != 'None', 'Qianfan access token invalid - check API/SECRET keys and account quota'

Type guard

def qianfan_frame_is_ok(dec: dict) -> bool:
    return isinstance(dec, dict) and 'result' in dec

Try / catch

try:
    for partial in generate_from_baidu_qianfan(inputs, llm_kwargs, history, sys_prompt):
        buffer = partial
except KeyError as e:
    if e.args[0] == 'error_msg':
        # original qianfan error frame lost - log raw lines and re-auth
        logging.error('qianfan sent error frame without error_msg')
        raise RuntimeError('qianfan stream error (schema missing error_msg)') from e
    raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of binary-husky/gpt_academic@d6bde0fa54 (2026-08-14). Data as JSON: /api/errors/22c320f151fcb170. Report an issue: GitHub.