usestrix/strix · warning · RuntimeError
Agent '{agent_id}' cannot be stopped while {status or 'unkno
Error message
Agent '{agent_id}' cannot be stopped while {status or 'unknown'} What it means
Raised by _stop_agent when the agent exists but its current status is not in _STOPPABLE_AGENT_STATUSES = {'running', 'waiting', 'budget_paused'} (controller.py:36). Strix only allows graceful cancellation of agents that are actively working or paused; agents that already completed, failed, or were cancelled cannot be stopped again. The message interpolates the actual status (or 'unknown' when the status field is empty).
Source
Thrown at strix/interface/tui/backend/controller.py:392
self.coordinator.send(
agent_id,
{"from": "user", "content": message, "type": "instruction"},
),
self.scan_loop,
)
delivered = await asyncio.wrap_future(future)
if not delivered:
raise RuntimeError("Message could not be delivered")
return {"sent": True}
async def _stop_agent(self, payload: dict[str, Any]) -> dict[str, Any]:
agent_id = self._required_string(payload, "agent_id")
agent = self.live_view.agents.get(agent_id)
if agent is None:
raise ValueError(f"Unknown agent: {agent_id}")
status = str(agent.get("status", ""))
if status not in _STOPPABLE_AGENT_STATUSES:
raise RuntimeError(f"Agent '{agent_id}' cannot be stopped while {status or 'unknown'}")
if self.coordinator is None or self.scan_loop is None or self.scan_loop.is_closed():
raise RuntimeError("Scan loop is not ready")
if self.scan_loop is asyncio.get_running_loop():
accepted = await self.coordinator.cancel_descendants_graceful(agent_id)
else:
future = asyncio.run_coroutine_threadsafe(
self.coordinator.cancel_descendants_graceful(agent_id), self.scan_loop
)
accepted = await asyncio.wrap_future(future)
if not accepted:
raise RuntimeError(f"Agent '{agent_id}' is no longer active")
return {"stopped": True}
async def _open_viewer(self, _payload: dict[str, Any]) -> dict[str, Any]:
if self.viewer_url:
with contextlib.suppress(Exception):
webbrowser.open(self.viewer_url)
return {"status": "running", "url": self.viewer_url}View on GitHub (pinned to 8551339130)
Solutions
- Check agent.get('status') is one of running/waiting/budget_paused before issuing stop
- Refresh live_view.agents and re-evaluate; if the agent already finished, no stop is needed
- Disable the stop control in the UI for non-stoppable statuses
- Treat 'completed'/'failed' agents as already stopped and remove them from actionable lists
Example fix
# before
await controller._stop_agent({"agent_id": aid})
# after
STOPPABLE = {"running", "waiting", "budget_paused"}
status = controller.live_view.agents.get(aid, {}).get("status", "")
if status in STOPPABLE:
await controller._stop_agent({"agent_id": aid}) Defensive patterns
Strategy: validation
Validate before calling
STOPPABLE = {"running", "waiting", "budget_paused"}
status = controller.live_view.agents.get(aid, {}).get("status", "")
if status not in STOPPABLE:
logging.info("agent %s already %s; no stop needed", aid, status or "unknown")
return Type guard
def agent_stoppable(agents: dict, aid: str) -> bool:
return agents.get(aid, {}).get("status", "") in {"running", "waiting", "budget_paused"} Try / catch
try:
await controller._stop_agent({"agent_id": aid})
except RuntimeError as e:
if "cannot be stopped while" in str(e):
pass # already finished/failed — treat as done
else:
raise Prevention
- Disable stop controls for agents outside running/waiting/budget_paused
- Refresh the status immediately before stopping
- Treat stop as idempotent: a finished agent needs no stop
When it happens
Trigger: Calling stop on an agent whose live_view status is e.g. 'completed', 'failed', 'cancelled', or missing/empty (renders as 'unknown'). Common double-click scenario: user hits stop right as the agent finishes.
Common situations: UI stop button not disabled for finished agents; racing a stop request with agent completion; stale agent row still showing in the panel; status field missing in custom agent snapshots.
Related errors
- Unknown agent: {agent_id}
- No target set. Add a target first.
- approved must be a boolean
- Agent coordinator is unavailable
- Agent '{agent_id}' is no longer active
AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15).
Data as JSON: /api/errors/f59ff38d301c73f4.
Report an issue: GitHub.