binary-husky/gpt_academic · error · RuntimeError

Json解析不合常规

Error message

Json解析不合常规

What it means

Catch-all error from bridge_ollama.predict_no_ui_long_connection: any exception while decoding a stream chunk (JSONDecodeError, KeyError on chunkjson['message']['content'], decode errors) falls into the except block, which drains the response via get_full_error for the real server message, logs it, and re-raises this generic RuntimeError. The true cause is in the logged error_msg, not the exception text.

Source

Thrown at request_llms/bridge_ollama.py:116

                    # 判定为数据流的结束,gpt_replying_buffer也写完了
                    logger.info(f'[response] {result}')
                    break
                result += chunkjson['message']["content"]
                if not console_silence: print(chunkjson['message']["content"], end='')
                if observe_window is not None:
                    # 观测窗,把已经获取的数据显示出去
                    if len(observe_window) >= 1:
                        observe_window[0] += chunkjson['message']["content"]
                    # 看门狗,如果超过期限没有喂狗,则终止
                    if len(observe_window) >= 2:
                        if (time.time()-observe_window[1]) > watch_dog_patience:
                            raise RuntimeError("用户取消了程序。")
            except Exception as e:
                chunk = get_full_error(chunk, stream_response)
                chunk_decoded = chunk.decode()
                error_msg = chunk_decoded
                logger.error(error_msg)
                raise RuntimeError("Json解析不合常规")
    return result


def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_prompt='', stream = True, additional_fn=None):
    """
    发送至chatGPT,流式获取输出。
    用于基础的对话功能。
    inputs 是本次问询的输入
    top_p, temperature是chatGPT的内部调优参数
    history 是之前的对话列表(注意无论是inputs还是history,内容太长了都会触发token数量溢出的错误)
    chatbot 为WebUI中显示的对话列表,修改它,然后yield出去,可以直接修改对话界面内容
    additional_fn代表点击的哪个按钮,按钮见functional.py
    """
    if inputs == "":     inputs = "空空如也的输入栏"
    user_input = inputs
    if additional_fn is not None:
        from core_functional import handle_core_functionality
        inputs, history = handle_core_functionality(additional_fn, inputs, history, chatbot)

View on GitHub (pinned to d6bde0fa54)

Solutions

  1. Read the logger.error output - it contains the raw chunk_decoded from get_full_error which identifies the real failure
  2. Verify OLLAMA_API_HOST / OLLAMA_URL points at a real Ollama /api/chat endpoint returning SSE JSON
  3. Check the model name in llm_kwargs exists on the Ollama server (ollama list)
  4. Test the same request with curl to inspect the raw stream frames
  5. Upgrade/downgrade Ollama to a version whose stream schema includes message.content in every frame

Example fix

# before
except Exception as e:
    ...
    raise RuntimeError("Json解析不合常规")

# after (surface the cause)
except Exception as e:
    chunk = get_full_error(chunk, stream_response)
    raise RuntimeError(f"Json解析不合常规: {chunk.decode(errors='replace')}") from e
Defensive patterns

Strategy: validation

Validate before calling

import requests
r = requests.get(f"{OLLAMA_API_HOST}/api/tags", timeout=5)
assert r.status_code == 200, f'Ollama endpoint broken: {r.status_code}'
assert llm_kwargs['llm_model'].replace('ollama-', '') in [m['name'] for m in r.json().get('models', [])]

Type guard

def is_valid_ollama_chunk(chunkjson: dict) -> bool:
    return (
        isinstance(chunkjson, dict)
        and isinstance(chunkjson.get('message'), dict)
        and isinstance(chunkjson['message'].get('content'), str)
    )

Try / catch

try:
    result = predict_no_ui_long_connection(...)
except RuntimeError as e:
    logging.getLogger().error('ollama stream failed, see logged chunk_decoded above')
    raise

Prevention

When it happens

Trigger: Ollama returning a non-JSON chunk (error page, proxy HTML); a chunk JSON without the 'message'/'content' keys (e.g. an error event frame); connection cut mid-chunk producing truncated bytes; wrong OLLAMA_API_HOST returning HTML.

Common situations: OLLAMA_API_HOST misconfigured or pointing at a reverse proxy that returns 4xx/5xx HTML; Ollama model name typo causing an error frame mid-stream; Ollama version emitting a different stream schema than the 'message.content' shape this bridge expects.

Related errors


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