usestrix/strix · error · RuntimeError
Agent coordinator is unavailable
Error message
Agent coordinator is unavailable
What it means
Raised by _send_message when the controller's coordinator reference is None, meaning no agent coordinator has been constructed yet. The coordinator is created during scan startup (_begin_scan), so this error means a chat message was routed to an agent before any scan exists. It is a state error, not a network error: the handler checks the invariant before attempting any delivery.
Source
Thrown at strix/interface/tui/backend/controller.py:363
mount = self.pending_workspace_mount
if mount is None:
raise RuntimeError("No mount confirmation is pending")
approved = payload.get("approved")
if not isinstance(approved, bool):
raise TypeError("approved must be a boolean")
self.pending_workspace_mount = None
# Declining skips the mount, it does not abandon the scan. The prompt is
# the whole of the input either way; the working directory is only an
# extra the agent may look at, so the run goes ahead without one.
self.workspace_mount = mount if approved else None
await self._begin_scan(self._pending_verify)
return {"approved": approved}
async def _send_message(self, payload: dict[str, Any]) -> dict[str, Any]:
agent_id = self._required_string(payload, "agent_id")
message = self._required_string(payload, "message")
if self.coordinator is None:
raise RuntimeError("Agent coordinator is unavailable")
if self.scan_loop is None or self.scan_loop.is_closed():
raise RuntimeError("Scan loop is not ready")
self.live_view.record_user_message(agent_id, message)
if self.scan_loop is asyncio.get_running_loop():
delivered = await self.coordinator.send(
agent_id,
{"from": "user", "content": message, "type": "instruction"},
)
else:
future = asyncio.run_coroutine_threadsafe(
self.coordinator.send(
agent_id,
{"from": "user", "content": message, "type": "instruction"},
),
self.scan_loop,
)
delivered = await asyncio.wrap_future(future)
if not delivered:View on GitHub (pinned to 8551339130)
Solutions
- Only enable the message input after the scan has started (scan_state == 'running' and coordinator exists)
- If the message was sent during startup, retry once the scan is live
- Guard the UI action on controller.scan_started / scan_state before dispatching send-message
- In tests, start a scan (or inject a fake coordinator) before exercising _send_message
Example fix
// before
await controller._send_message({"agent_id": "planner", "message": "hi"})
// after
if controller.scan_started:
await controller._send_message({"agent_id": "planner", "message": "hi"}) Defensive patterns
Strategy: validation
Validate before calling
if controller.coordinator is None or not controller.scan_started:
show_status("Start a scan before messaging agents")
return Type guard
def scan_ready(c) -> bool:
return c.coordinator is not None and c.scan_started and c.scan_state == "running" Try / catch
try:
await controller._send_message(payload)
except RuntimeError as e:
if "coordinator is unavailable" in str(e):
disable_chat_input() # scan not started yet
else:
raise Prevention
- Gate chat UI on scan_state == 'running'
- Disable the message box on the setup screen
- Tear down UI handlers when the controller resets so late dispatches cannot occur
When it happens
Trigger: Invoking the send-message command with valid agent_id/message strings before a scan has started (coordinator is None), or after the controller was reset and the coordinator torn down. The agent_id and message fields already passed _required_string validation when this fires.
Common situations: Frontend fires a chat send during the setup screen; a queued message is dispatched after scan teardown; race between the UI enabling the chat input and the backend creating the coordinator; tests instantiating the controller without starting a scan.
Related errors
- Scan loop is not ready
- Setup can no longer be changed after the scan starts
- Message could not be delivered
- Agent '{agent_id}' cannot be stopped while {status or 'unkno
- The interactive interface could not start: {exc}
AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15).
Data as JSON: /api/errors/eff569da82a875c2.
Report an issue: GitHub.