Skip to content

fix(app): composer reloads a stale-empty agent/provider catalog before refusing a send - #2162

Open
jacktrnr wants to merge 1 commit into
mainfrom
fix/composer-model-guard-retry
Open

jacktrnr wants to merge 1 commit into
mainfrom
fix/composer-model-guard-retry

Conversation

@jacktrnr

@jacktrnr jacktrnr commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

Problem

After a dev-mode "Rebuild from Main" plus a window reload, every send in every session was refused with "Select an agent and model", even with a model picked. The window kept refusing until the next reload.

The failing window was running the same build as a working one. That 10:53 rebuild never deployed, and the window reloaded mid-rebuild. The engine log shows a config re-init at 15:55:51Z, triggered when the rebuild re-staged agent cards, and during it a request failed (ENOENT on a deleted project folder). bootstrapDirectory loads the agent list once (ensureQueryData(loadAgentsQuery…).then(setStore("agent", …))), with no retry after that. If that one request fails, store.agent stays [] for the window's lifetime, local.agent.current() is undefined, and the guard at submit.ts:425 refuses every send. Its message wrongly blames the model.

Fix

  • context/server-sync.tsx: new reloadCatalog(directory). It re-fetches the agent list with staleTime: 0 (so a cached failure isn't reused), writes it back into the child store, and refetches every providers query. It is single-flight per directory.
  • components/prompt-input/catalog-recovery.ts: new resolveWithCatalogRecovery, a pure function. It reads the selection, and if anything is missing it reloads once, bounded at 8 s with errors swallowed, then reads again.
  • submit.ts: the guard goes through the recovery step before refusing, and the refusal now names what is missing:
    • Agents didn't load: "Couldn't load the agent list from the engine, even after retrying. Nothing was sent. Reload the window…"
    • Selected model isn't available: "The selected model's provider isn't connected…"
  • The agent is never defaulted. An unresolved agent is refused, not swapped for build, because that would quietly give a plan-mode chat write access.

Verification

  • catalog-recovery.test.ts: 14 tests.
    • Recovery: a resolved selection skips the reload; an empty agent list recovers; a disconnected provider recovers; agent missing gives "agent" (never a default); model missing gives "model"; both missing gives "agent"; a throwing reload is swallowed; a hanging reload is bounded by the timeout.
    • Single-flight: concurrent calls share one run, and different keys run independently.
    • Source pins on the submit.ts and server-sync.tsx wiring.
  • src/components/prompt-input suite: 95 pass, 4 fail, 3 errors. The same 4 failures and 3 errors happen on unmodified main; they are import errors at module load in submit.test.ts, submit-concise.test.ts and harness.test.ts.
  • Overlay typecheck gate: clean across 7 packages.
  • refresh_manifest then drift_gate: PASS.
  • ./.notturno/gates: GREEN.
  • Not reproduced by hand in a live window. The failure needs a request to fail during an engine re-init. Recovery is covered by the unit tests, not an end-to-end test.

…e refusing a send

The directory bootstrap loads the agent list once; if that request failed
(engine mid re-init, e.g. while a rebuild re-stages its config) the list stayed
empty for the window's lifetime and every send was refused with "Select an
agent and model" even though a model was picked. The send guard now reloads
the catalog once (agents fresh + all providers queries, single-flight, 8 s
bound) and re-reads before refusing; the refusal names what is missing
(agents didn't load / selected model's provider isn't connected). The agent is
never defaulted to build.
@coderabbitai

coderabbitai Bot commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 1695d9f3-66e3-4287-86b4-72e6134a0d6a
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant