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.
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
hermesCLI andhermes --tuido not show this symptom; the same session resumed viahermesCLI works fine - Composer chrome consistently shows
default · backend · GPT-5.4 Mini · lowafter the error, even thoughgpt-5.5is 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 modelto select a provider, or runhermes setupfor 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.

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:

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:
- The session's
model_provideris being cleared and the resolver falls back to "first openai-codex-flavored mini we can find" — butgpt-5.5-miniis first, so something is filtering further. - 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.
-
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.
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 compressing → compressed 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

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_providercorruption (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_providermutation 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:
- 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..."). - 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/modelpair, hence thegpt-5.4-miniregression in the composer. - 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 configuredand 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_provideror re-derives it from config/env - Confirm whether the openai-codex codepath in
agent_init.py:761-804(_fb_resolvedfallback) requires akey_env/api_key, which it cannot have on OAuth — this looks like the most likely silent failure - Confirm whether the
compressing→compressedSSE 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
/compressasync start/status (parallel surface area) - PR #2077 (#2028) —
api/compression_anchor.pyextracted helpers (same module family)
Three interrelated streaming/compression-boundary symptoms that brick sessions and silently downgrade models indicate a cross-cutting backend-frontend state bug requiring deep investigation.
- api/agent_init.py
- api/session.py
- api/streaming.py
- api/compression.py
- static/composer.js
- static/streaming.js
- static/model-selector.js