{"record":{"id":"8cc8279b4740ec54","repo":"binary-husky/gpt_academic","slug":"chunk-decoded-8cc827","errorCode":null,"errorMessage":"无法读取以下数据，请检查配置。\n\n{chunk_decoded}","messagePattern":"无法读取以下数据，请检查配置。\n\n(.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"request_llms/bridge_openrouter.py","lineNumber":332,"sourceCode":"                # 其他情况，直接返回报错\n                chatbot, history = handle_error(inputs, llm_kwargs, chatbot, history, chunk_decoded, error_msg)\n                yield from update_ui(chatbot=chatbot, history=history, msg=\"非OpenAI官方接口返回了错误:\" + chunk.decode()) # 刷新界面\n                return\n\n            # 提前读取一些信息 （用于判断异常）\n            chunk_decoded, chunkjson, has_choices, choice_valid, has_content, has_role = decode_chunk(chunk)\n\n            if is_head_of_the_stream and (r'\"object\":\"error\"' not in chunk_decoded) and (r\"content\" not in chunk_decoded):\n                # 数据流的第一帧不携带content\n                is_head_of_the_stream = False; continue\n\n            if chunk:\n                try:\n                    if (has_choices and not choice_valid) or chunk_decoded.startswith(':'):\n                        continue\n                    if ('data: [DONE]' not in chunk_decoded) and len(chunk_decoded) > 0 and (chunkjson is None):\n                        # 传递进来一些奇怪的东西\n                        raise ValueError(f'无法读取以下数据，请检查配置。\\n\\n{chunk_decoded}')\n                    # 前者是API2D的结束条件，后者是OPENAI的结束条件\n                    if ('data: [DONE]' in chunk_decoded) or (len(chunkjson['choices'][0][\"delta\"]) == 0):\n                        # 判定为数据流的结束，gpt_replying_buffer也写完了\n                        log_chat(llm_model=llm_kwargs[\"llm_model\"], input_str=inputs, output_str=gpt_replying_buffer)\n                        break\n                    # 处理数据流的主体\n                    status_text = f\"finish_reason: {chunkjson['choices'][0].get('finish_reason', 'null')}\"\n                    # 如果这里抛出异常，一般是文本过长，详情见get_full_error的输出\n                    if has_content:\n                        # 正常情况\n                        gpt_replying_buffer = gpt_replying_buffer + chunkjson['choices'][0][\"delta\"][\"content\"]\n                    elif has_role:\n                        # 一些第三方接口的出现这样的错误，兼容一下吧\n                        continue\n                    else:\n                        # 至此已经超出了正常接口应该进入的范围，一些垃圾第三方接口会出现这样的错误\n                        if chunkjson['choices'][0][\"delta\"][\"content\"] is None: continue # 一些垃圾第三方接口出现这样的错误，兼容一下吧\n                        gpt_replying_buffer = gpt_replying_buffer + chunkjson['choices'][0][\"delta\"][\"content\"]","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/request_llms/bridge_openrouter.py#L314-L350","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read chunk_decoded in the message - it shows exactly what came back (usually an HTML error page or JSON error body)","Verify API_URL_REDIRECT / the model's base URL points to a valid /v1/chat/completions SSE endpoint","Check the API key is set and accepted (test with curl -N)","If a relay is involved, confirm it forwards SSE without buffering or rewriting"],"exampleFix":"# before\nAPI_URL_REDIRECT = \"https://my-relay.example.com\"\n\n# after\nAPI_URL_REDIRECT = \"https://my-relay.example.com/v1/chat/completions\"","handlingStrategy":"validation","validationCode":"import requests\nr = requests.post(api_url, headers=headers,\n                  json={'model': model, 'stream': True, 'messages': [{'role': 'user', 'content': 'ping'}], 'max_tokens': 1},\n                  stream=True, timeout=15)\nfirst = next(r.iter_lines())\nassert first.lstrip(b'data: ').startswith(b'{'), f'not SSE JSON: {first[:120]!r}'","typeGuard":"def chunk_is_openai_sse(line: bytes) -> bool:\n    s = line.decode('utf-8', errors='replace').strip()\n    return s.startswith('data:') or s == '' or s.startswith(':')","tryCatchPattern":"try:\n    yield from predict(inputs, llm_kwargs, ...)\nexcept ValueError as e:\n    if '无法读取以下数据' in str(e):\n        show_config_error(str(e))  # embeds raw payload for diagnosis\n    raise","preventionTips":["Smoke-test the endpoint with a 1-token streamed request before long jobs","Verify base URL ends with /v1/chat/completions for relays (one-api/new-api/vllm)","Never point the bridge at an HTML-returning URL - this error is the symptom"],"tags":["openrouter","configuration","json","sse","base-url"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}