open-webui / open-webui/computer

Bug: Startup crash when OpenCode agent profile is auto-detected — cptr tries to JSON-parse opencode serve's plain-text stdout

Open
#222 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
569
Forks
79
PR merge metrics
No merged PRs in 30d

Description

cptr (installed via uvx cptr@latest run) crashes on startup with an unhandled JSONDecodeError when it auto-detects a locally installed opencode CLI and probes it as an agent profile. This kills the entire FastAPI app during lifespan startup, not just that one profile.

Environment:

  • Arch Linux
  • opencode installed via pacman/AUR, fully functional and logged in
  • cptr run via uvx cptr@latest run
  • Python 3.14 (via uv's resolved interpreter) — also reproduced when pinning --python 3.12, so not Python-version-specific

Traceback:
File ".../cptr/app.py", line 67, in lifespan
await warm_model_cache(app.state)
File ".../cptr/routers/chat.py", line 281, in warm_model_cache
await asyncio.gather(*tasks)
File ".../cptr/utils/agents/detection.py", line 690, in get_available_agent_model_entries
status = await get_agent_status(app_state)
File ".../cptr/utils/agents/detection.py", line 648, in get_agent_status
detected = await detect_profile(profile)
File ".../cptr/utils/agents/detection.py", line 267, in detect_profile
models = await _probe_acp_models(command, profile, auth_method_id="oauth-personal")
File ".../cptr/utils/agents/detection.py", line 589, in _probe_acp_models
await client.close()
File ".../cptr/utils/agents/acp.py", line 85, in close
await task
File ".../cptr/utils/agents/acp.py", line 183, in _reader_loop
extracted = _extract_json_message(buffer)
File ".../cptr/utils/agents/acp.py", line 261, in _extract_json_message
return json.loads(line.decode()), buffer[line_end + 1 :]
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Root cause (confirmed via manual reproduction):
For the OpenCode profile type, cptr spawns:
opencode serve --hostname=127.0.0.1 --port=
Running that exact command by hand shows opencode writes plain human-readable log lines to stdout on startup, not JSON:
Warning: OPENCODE_SERVER_PASSWORD is not set; server is unsecured.
opencode server listening on http://127.0.0.1:47645
cptr's _reader_loop/_extract_json_message appears to treat this subprocess's stdout as a newline-delimited JSON-RPC stream (the ACP convention used for other agent types), and immediately fails json.loads() on the first non-JSON line. This is reproducible even with a no-op stub binary named opencode on PATH that produces zero stdout output before exiting — json.loads("") throws the identical error, confirming this isn't about opencode's specific output but about cptr expecting JSON where serve mode never produces it.

Impact: Any user with opencode installed and discoverable on PATH cannot start cptr at all — a single bad profile probe takes down the entire app during lifespan startup (asyncio.gather(*tasks) in warm_model_cache has no per-task error isolation, and detect_profile/_probe_acp_models don't catch JSONDecodeError).

Suggested fixes:

  1. Catch and isolate per-profile detection errors in warm_model_cache/get_available_agent_model_entries so one broken agent profile can't crash app startup.
  2. For the OpenCode profile type specifically, don't reuse the ACP JSON-RPC stdout reader against opencode serve — its stdout is plain log text, not JSON-RPC; communication should happen over HTTP against the bound port instead.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with cptr/app.py:67 and cptr/routers/chat.py:281, then trace detection through cptr/utils/agents/detection.py and cptr/utils/agents/acp.py. Reproduce the OpenCode probe and inspect _reader_loop and _extract_json_message. Done means startup survives a failed or non-JSON profile probe and OpenCode detection no longer treats serve output as JSON-RPC, with relevant tests passing.

Written by the indexing model from the issue text.

Assessment

Tech stack
fastapi, python
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.