binary-husky/gpt_academic · error · ValueError

无法读取以下数据,请检查配置。 {chunk_decoded}

Error message

无法读取以下数据,请检查配置。

{chunk_decoded}

What it means

ValueError from bridge_openrouter.predict (the UI streaming path): decode_chunk returned chunkjson=None for a non-empty frame that is not 'data: [DONE]', meaning the payload could not be parsed as an OpenAI JSON object at all. The offending raw chunk_decoded is embedded in the message so the misconfiguration is visible.

Source

Thrown at request_llms/bridge_openrouter.py:332

                # 其他情况,直接返回报错
                chatbot, history = handle_error(inputs, llm_kwargs, chatbot, history, chunk_decoded, error_msg)
                yield from update_ui(chatbot=chatbot, history=history, msg="非OpenAI官方接口返回了错误:" + chunk.decode()) # 刷新界面
                return

            # 提前读取一些信息 (用于判断异常)
            chunk_decoded, chunkjson, has_choices, choice_valid, has_content, has_role = decode_chunk(chunk)

            if is_head_of_the_stream and (r'"object":"error"' not in chunk_decoded) and (r"content" not in chunk_decoded):
                # 数据流的第一帧不携带content
                is_head_of_the_stream = False; continue

            if chunk:
                try:
                    if (has_choices and not choice_valid) or chunk_decoded.startswith(':'):
                        continue
                    if ('data: [DONE]' not in chunk_decoded) and len(chunk_decoded) > 0 and (chunkjson is None):
                        # 传递进来一些奇怪的东西
                        raise ValueError(f'无法读取以下数据,请检查配置。\n\n{chunk_decoded}')
                    # 前者是API2D的结束条件,后者是OPENAI的结束条件
                    if ('data: [DONE]' in chunk_decoded) or (len(chunkjson['choices'][0]["delta"]) == 0):
                        # 判定为数据流的结束,gpt_replying_buffer也写完了
                        log_chat(llm_model=llm_kwargs["llm_model"], input_str=inputs, output_str=gpt_replying_buffer)
                        break
                    # 处理数据流的主体
                    status_text = f"finish_reason: {chunkjson['choices'][0].get('finish_reason', 'null')}"
                    # 如果这里抛出异常,一般是文本过长,详情见get_full_error的输出
                    if has_content:
                        # 正常情况
                        gpt_replying_buffer = gpt_replying_buffer + chunkjson['choices'][0]["delta"]["content"]
                    elif has_role:
                        # 一些第三方接口的出现这样的错误,兼容一下吧
                        continue
                    else:
                        # 至此已经超出了正常接口应该进入的范围,一些垃圾第三方接口会出现这样的错误
                        if chunkjson['choices'][0]["delta"]["content"] is None: continue # 一些垃圾第三方接口出现这样的错误,兼容一下吧
                        gpt_replying_buffer = gpt_replying_buffer + chunkjson['choices'][0]["delta"]["content"]

View on GitHub (pinned to d6bde0fa54)

Solutions

  1. Read chunk_decoded in the message - it shows exactly what came back (usually an HTML error page or JSON error body)
  2. Verify API_URL_REDIRECT / the model's base URL points to a valid /v1/chat/completions SSE endpoint
  3. Check the API key is set and accepted (test with curl -N)
  4. If a relay is involved, confirm it forwards SSE without buffering or rewriting

Example fix

# before
API_URL_REDIRECT = "https://my-relay.example.com"

# after
API_URL_REDIRECT = "https://my-relay.example.com/v1/chat/completions"
Defensive patterns

Strategy: validation

Validate before calling

import requests
r = requests.post(api_url, headers=headers,
                  json={'model': model, 'stream': True, 'messages': [{'role': 'user', 'content': 'ping'}], 'max_tokens': 1},
                  stream=True, timeout=15)
first = next(r.iter_lines())
assert first.lstrip(b'data: ').startswith(b'{'), f'not SSE JSON: {first[:120]!r}'

Type guard

def chunk_is_openai_sse(line: bytes) -> bool:
    s = line.decode('utf-8', errors='replace').strip()
    return s.startswith('data:') or s == '' or s.startswith(':')

Try / catch

try:
    yield from predict(inputs, llm_kwargs, ...)
except ValueError as e:
    if '无法读取以下数据' in str(e):
        show_config_error(str(e))  # embeds raw payload for diagnosis
    raise

Prevention

When it happens

Trigger: API URL pointing at a non-SSE endpoint (HTML login page, 404 body); wrong BASE_URL for a self-hosted vllm/one-api relay; missing API key causing an auth error body streamed as data; proxy injecting non-JSON bytes.

Common situations: Misconfigured API_URL_REDIRECT / base URL; one-api/new-api deployments with wrong path; provider outage returning plain-text errors; custom reverse proxy breaking SSE.

Related errors


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