github →

New request

#2761: WebUI mid-conversation: "No LLM provider configured" bricks the session until a fork; assistant response sometimes vanishes into an "Auto-compressing..." card; model silently reverts to gpt-5.4-mini

We'll provision a sandbox, run an agent against the issue, and open a draft PR. You can pull the branch and iterate from there.

Issue
bugupstream-changesprint-candidateinvestigationstreaming

WebUI mid-conversation: "No LLM provider configured" bricks the session until a fork; assistant response sometimes vanishes into an "Auto-compressing..." card; model silently reverts to gpt-5.4-mini

Reported by Maheśvara in Discord #report-bugs (May 21 2026). Three connected symptoms, all centered on the auto-compression boundary. Original thread: https://discord.com/channels/1492983281338286121/1493325333980774622 (May 21 11:17 AM / 12:08 PM / 12:19 PM).

Environment (from the report)

  • Provider: OpenAI Codex (ChatGPT subscription / OAuth, not API key)
  • Configured default model: gpt-5.5
  • Reported behavior continues across manual WebUI process restart and provider re-configuration
  • Vanilla hermes CLI and hermes --tui do not show this symptom; the same session resumed via hermes CLI works fine
  • Composer chrome consistently shows default · backend · GPT-5.4 Mini · low after the error, even though gpt-5.5 is the configured default

Symptom 1 — Mid-conversation "No LLM provider configured" bubble

After an arbitrary number of working turns, a turn fails with the standard agent_init.py error rendered as an assistant message:

Error: No LLM provider configured. Run hermes model to select a provider, or run hermes setup for first-time configuration.

From that point on every follow-up in the same thread returns the same error. The conversation is bricked. The only recovery the user has found is fork the previous response, after which the new branch runs normally with the user's configured provider.

Error bubble in context

The bubble text matches agent/agent_init.py:807-811 (raise RuntimeError("No LLM provider configured. Run \hermes model` to select a provider, or run `hermes setup` for first-time configuration.")), which only fires inside AIAgent.init()when no explicit provider, no env-var key, and nofallback_model` entry resolves. That code path should not be reachable mid-session for a session that was successfully created and has been making LLM calls — implying either (a) provider state is being cleared/reset on the active agent, or (b) a fresh agent is being constructed without the session's resolved provider being threaded back in.

The fact that fork-and-retry on the same session immediately works (and hermes CLI continues the same session without issue) points squarely at the WebUI's request-time provider resolution, not at the credential layer itself.

Symptom 2 — Composer silently reverts to gpt-5.4-mini

When the error fires, the composer model chip flips to GPT-5.4 Mini even though the user's configured default is GPT-5.5:

Composer footer showing GPT-5.4 Mini

api/config.py:1043-1058 shows gpt-5.4-mini is the fourth entry in both the openai and openai-codex _PROVIDER_MODELS lists. It is not the first entry, not a documented fallback, and not something the user picked. The fact that the picker lands on this specific id when the session goes sideways suggests something in the resolver is reaching for a hardcoded openai-codex catalog entry rather than honouring the session's stored model_provider/model pair.

Two hypotheses, both worth checking in api/config.py:resolve_model_provider and the streaming session-init path:

  1. The session's model_provider is being cleared and the resolver falls back to "first openai-codex-flavored mini we can find" — but gpt-5.5-mini is first, so something is filtering further.
  2. A credential-pool / quota / OAuth refresh path is silently downgrading the chosen model to gpt-5.4-mini (the only currently-shipped non-codex non-premium id in the codex list) without bubbling that decision into either the assistant message or the composer label other than the bare "No LLM provider configured" error.

Codex subscription is specifically called out by the reporter as their auth path — likely relevant since openai-codex is ChatGPT OAuth-backed (no OPENAI_API_KEY required) and its credential resolution path differs materially from the keyed providers.

Symptom 3 — Compression cycle "deletes" the assistant response, only blue card visible

This is the most diagnostic part of the report. After a request completes:

  • Blue / "running" compaction card (Auto-compressing context to continue... · 01:46) is rendered, but the assistant's response itself is not visible — only the user message and the running-state compaction card. To see the response the user re-sends the same prompt, which triggers another full compression cycle.

    Response invisible, blue compaction card

  • Green / "done" compaction card (Automatic compression · Context auto-compressed to continue the conversation) — when the settled card is visible, the response is present and the conversation continues normally.

    Green settled compaction card

Reporter's verbatim summary: "the conversation started back working once I got the green compaction chat bubble. It seems like these blue ones just caused the message missing error, but when I saw the bubble green, the conversation continued working."

So: the transition compressingcompressed is not reliably promoting the running card to the settled card AND is leaving the response hidden behind whatever DOM the running card occupies. The user has discovered a manual workaround: resend → triggers a second compression → settles green → response now visible.

PR #1838 (closes #1832) wired compressing SSE → setCompressionUi({phase:'running', automatic:true}) and is supposed to flow into the existing compressed listener for the settled state. The ordering invariant is tested (tests/test_auto_compression_card.py). So the bridge is correct in source — but in practice the running phase appears to be eating the assistant message render until the user forces a second cycle.

Note: this overlaps in shape with #2613 (Persisted assistant diff output and tool activity can disappear after settled render), but the trigger here is explicitly the running compression card rather than a settled-render reconciliation. Worth investigating whether they share a root or whether this is a distinct race in the streaming → compression handoff.

CLI parity check (rules these out)

No issue like this with vanilla hermes or hermes --tui

CLI continuation works, WebUI bricked

The reporter can resume the exact same session via hermes CLI and continue normally. This rules out:

  • Credential file corruption (auth.json / .env)
  • Profile-level model_provider corruption (the session row still resolves correctly on CLI replay)
  • A genuine "no provider configured" state on disk

…and pins this to one of:

  • WebUI request-time provider resolution / cached-agent rebuild after compression
  • A model_provider mutation that happens on the WebUI HTTP path but not on the CLI path
  • A streaming/SSE reconciliation race that drops the response and presents the bubble as a fake "agent init failed" error when the real failure was something else (timeout / OAuth refresh / quota / proxy)

Suspected area

api/streaming.py + agent/agent_init.py + api/config.py::resolve_model_provider + api/compression_anchor.py. The three symptoms share a single trigger (compression cycle finishes) and a single auth context (openai-codex / ChatGPT OAuth). The shape suggests:

  1. After auto-compression, the streaming code rebuilds (or re-resolves) the agent and the openai-codex credential resolution silently fails to find a key (because there isn't one — it's OAuth) and the codex-aware fallback path doesn't fire, raising RuntimeError("No LLM provider configured...").
  2. The model field on the rebuilt agent kwargs is being set from a stale or default codex catalog rather than from the session's model_provider/model pair, hence the gpt-5.4-mini regression in the composer.
  3. The running-phase compression card is occupying the message slot where the assistant turn would render, and the settled card swap isn't happening on the affected paths, hence the "response disappeared" symptom.

Repro inputs from the report

  • WebUI v0.51.x with openai-codex (ChatGPT subscription / OAuth) as the active provider
  • Default model gpt-5.5
  • Long-running conversation that crosses the auto-compression threshold
  • After compression triggers, watch for: (a) bricked thread with No LLM provider configured and only fork-recovery works, (b) composer chip shows GPT-5.4 Mini, (c) blue compaction card persists and response is invisible until manual resend.

Asks for the fix PR

  • Reproduce on Codex OAuth flow + a long-context test that triggers auto-compression
  • Confirm whether the agent rebuild after auto-compression re-uses the session's stored model_provider or re-derives it from config/env
  • Confirm whether the openai-codex codepath in agent_init.py:761-804 (_fb_resolved fallback) requires a key_env/api_key, which it cannot have on OAuth — this looks like the most likely silent failure
  • Confirm whether the compressingcompressed SSE transition is delivering the settled card on the user-visible path, not only in the regression tests
  • Add an integration test covering: long-session w/ codex OAuth provider → cross compression threshold → assert subsequent turn does not raise No LLM provider configured

Labels

bug, sprint-candidate, streaming, providers, investigation

Related

  • #2613 — Persisted assistant diff output and tool activity can disappear after settled render (similar "response disappears" shape, different trigger)
  • #1838 / #1832 — PR that wired the compressing SSE → running card (the bridge that's apparently failing on the user-visible path here)
  • PR #2128 (#2087) — manual /compress async start/status (parallel surface area)
  • PR #2077 (#2028) — api/compression_anchor.py extracted helpers (same module family)
Assessmentadvisory
bug●●● hard85% confidence

Three interrelated streaming/compression-boundary symptoms that brick sessions and silently downgrade models indicate a cross-cutting backend-frontend state bug requiring deep investigation.

Likely files
  • api/agent_init.py
  • api/session.py
  • api/streaming.py
  • api/compression.py
  • static/composer.js
  • static/streaming.js
  • static/model-selector.js
Create the request

This opens a fresh agent run and a draft PR for issue #2761.

Cancel