hermes - 💡(How to fix) Fix Kanban workers crash (protocol violation) when display.interface: tui — headless worker launches TUI, exits rc=0

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Kanban workers crash with a protocol violation when display.interface: tui is set in the dispatcher's config.yaml. The headless worker subprocess launches the Ink TUI, detects no TTY, prints the resume hint, and exits rc=0 without ever running the agent loop — so it never calls kanban_complete/kanban_block.

Version: Hermes Agent v0.15.1 (2026.5.29)

Root Cause

The dispatcher spawns each worker as (hermes_cli/kanban_db.py, _default_spawn, ~L6711–6770):

hermes -p <profile> --accept-hooks [--skills ...] chat -q "work kanban task <id>"

with stdin=subprocess.DEVNULL and start_new_session=True. The argv contains no --cli flag.

cmd_chat_resolve_use_tui(args) (hermes_cli/main.py:1901) resolves the interface with precedence:

  1. --cli flag → CLI
  2. --tui / HERMES_TUI=1 → TUI
  3. display.interface config value
  4. default → CLI

Because the worker argv passes neither --cli nor --tui, resolution falls through to display.interface. With tui configured, the worker hands off to ui-tui/dist/entry.js, which hits the no-TTY guard (ui-tui/src/entry.tsx:18, console.log('hermes-tui: no TTY')), prints the "Resume this session" hint, and exits 0.

The agent loop never starts, so the kanban lifecycle tools are never called. The dispatcher correctly flags worker exited cleanly (rc=0) without calling kanban_complete or kanban_block — protocol violation, retries, and trips the circuit breaker after failure_limit.

Fix Action

Workaround

Set display.interface: cli in the dispatcher's config.yaml and launch the TUI explicitly with hermes --tui when interactive. This unblocks workers but forfeits TUI-as-default for bare hermes.

Code Example

hermes -p <profile> --accept-hooks [--skills ...] chat -q "work kanban task <id>"

---

# reproduces the crash (honors config tui):
hermes -p default chat -q "..."         < /dev/null   # → "hermes-tui: no TTY", exit 0

# runs the headless agent loop correctly:
hermes -p default chat --cli -q "..."    < /dev/null   # → agent initializes, completes

---

cmd.extend(["chat", "--cli", "-q", prompt])
RAW_BUFFERClick to expand / collapse

Summary

Kanban workers crash with a protocol violation when display.interface: tui is set in the dispatcher's config.yaml. The headless worker subprocess launches the Ink TUI, detects no TTY, prints the resume hint, and exits rc=0 without ever running the agent loop — so it never calls kanban_complete/kanban_block.

Version: Hermes Agent v0.15.1 (2026.5.29)

Root cause

The dispatcher spawns each worker as (hermes_cli/kanban_db.py, _default_spawn, ~L6711–6770):

hermes -p <profile> --accept-hooks [--skills ...] chat -q "work kanban task <id>"

with stdin=subprocess.DEVNULL and start_new_session=True. The argv contains no --cli flag.

cmd_chat_resolve_use_tui(args) (hermes_cli/main.py:1901) resolves the interface with precedence:

  1. --cli flag → CLI
  2. --tui / HERMES_TUI=1 → TUI
  3. display.interface config value
  4. default → CLI

Because the worker argv passes neither --cli nor --tui, resolution falls through to display.interface. With tui configured, the worker hands off to ui-tui/dist/entry.js, which hits the no-TTY guard (ui-tui/src/entry.tsx:18, console.log('hermes-tui: no TTY')), prints the "Resume this session" hint, and exits 0.

The agent loop never starts, so the kanban lifecycle tools are never called. The dispatcher correctly flags worker exited cleanly (rc=0) without calling kanban_complete or kanban_block — protocol violation, retries, and trips the circuit breaker after failure_limit.

Reproduction

  1. Set display.interface: tui in ~/.hermes/config.yaml.
  2. Create any kanban task and let the in-gateway dispatcher claim it.
  3. Worker crashes every attempt → task auto-blocks after failure_limit consecutive failures.

The per-task worker log (<board>/logs/<task>.log) shows only the repeated TUI no-TTY hint, one block per attempt — never any agent output.

Confirmed minimal repro / fix on the same install:

# reproduces the crash (honors config tui):
hermes -p default chat -q "..."         < /dev/null   # → "hermes-tui: no TTY", exit 0

# runs the headless agent loop correctly:
hermes -p default chat --cli -q "..."    < /dev/null   # → agent initializes, completes

Note: a parent-level hermes --cli chat ... does not fix it — the chat subparser also defines --cli and its default (False) clobbers the parent value, so --cli must be placed after the chat subcommand. This argparse subparser-clobber is a contributing sharp edge.

Expected

Headless worker subprocesses are non-interactive by definition (stdin=DEVNULL, detached session). They should never launch the TUI regardless of display.interface.

Proposed fix

Inject --cli into the worker argv in _default_spawn so headless workers are always forced to the classic CLI path, independent of the operator's interactive display.interface preference:

cmd.extend(["chat", "--cli", "-q", prompt])

(Same reasoning likely applies to any other place the dispatcher/cron spawns a detached chat subprocess.)

Workaround

Set display.interface: cli in the dispatcher's config.yaml and launch the TUI explicitly with hermes --tui when interactive. This unblocks workers but forfeits TUI-as-default for bare hermes.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING