Skip to content

fix(tui): one-shot run hangs forever when a precondition is unmet #2483

Description

@kovtcharov

Why this matters

gaia tui run <id> --query "..." is the scriptable, CI-friendly path — the one that exists so automation doesn't need a human at a terminal. With the local model server down it hangs indefinitely and prints nothing at all. No stdout, no stderr, no exit. A CI job wedges until its own timeout kills it, with nothing in the log to say why.

This is the exact failure the readiness gate was built to prevent, and the one-shot is the path that needs it most: an interactive user sees a blank screen and presses ctrl-C, but a script just stops.

Before: silent hang, forever, no diagnostic.
After: fails in seconds naming the unmet precondition and the command to fix it.

Repro

Verified with the local model server confirmed down:

$ curl -s -m 3 http://localhost:13305/api/v1/health   # no response — server is down
$ gaia tui run email --query "triage my inbox"
  …200+ seconds, no output on stdout or stderr, no exit

Cause

RunAgent goes straight to RunOneShot with context.Background() — no readiness check and no deadline, so an unreachable backend has nothing to fail against.

The interactive path does not have this problem: launching from the hub now runs the preflight gate, which reports the same condition as a checkable row with a remedy.

Fix direction

Two things, and the second matters even if the first lands:

  1. Run the readiness check on the one-shot path. It should not render the interactive gate — a script has nobody to press a key — but it should fail with the same actionable message the gate would have shown, and a non-zero exit.
  2. Give the one-shot a deadline regardless. context.Background() means any unreachable dependency hangs forever; a bounded context turns that into a reportable error. The headless preflight.Check(ctx, …) already exists and is usable without the UI.

This was flagged during review as "presumably deliberate for the scripting path" — it is reasonable not to show a gate, but the current behaviour isn't a skipped gate, it's an unbounded wait.

Test plan

  • With the model server stopped, gaia tui run email --query "hi" exits non-zero within seconds and names the remedy
  • The message matches what the interactive gate reports for the same condition
  • With everything healthy, the one-shot still answers on stdout and exits 0
  • A dependency that hangs rather than refuses also hits the deadline

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions