usestrix/strix · error · RuntimeError
Cannot resume scan {scan_id}: agents.json has no root agent
Error message
Cannot resume scan {scan_id}: agents.json has no root agent (parent=None) What it means
Raised on the resume path (strix/core/runner.py:219) after coordinator.restore(snap) succeeds but no agent in the restored parent_of map has parent None — i.e. the snapshot contains no root agent. Every Strix scan graph must have exactly one root agent (parent=None) to drive the run; a snapshot with only sub-agents is structurally invalid and resume is refused.
Source
Thrown at strix/core/runner.py:219
await coordinator.restore(snap)
report_state = get_global_report_state()
if report_state is not None:
budget_stopped, reserve_stopped = recomputed_budget_flags(
report_state.get_total_llm_cost(),
max_budget_usd,
interactive=interactive,
)
await coordinator.reset_budget_stops(
budget_stopped=budget_stopped,
reserve_stopped=reserve_stopped,
budget_paused=interactive and coordinator.budget_paused,
)
for aid, parent in coordinator.parent_of.items():
if parent is None:
root_id = aid
break
if root_id is None:
raise RuntimeError(
f"Cannot resume scan {scan_id}: agents.json has no root agent (parent=None)",
)
logger.info(
"Resume: restored coordinator with %d agent(s); root=%s",
len(coordinator.statuses),
root_id,
)
else:
root_id = uuid.uuid4().hex[:8]
logger.info("Bringing up sandbox session for scan %s", scan_id)
bundle = await session_manager.create_or_reuse(
scan_id,
image=image,
local_sources=local_sources or [],
extra_files=extra_files,
status_sink=status_sink,
)View on GitHub (pinned to 8551339130)
Solutions
- Inspect agents.json and verify one entry has "parent": null; if absent, the snapshot is not a complete scan graph.
- Resume with the same Strix version that produced the run (pip/uv pin) so the snapshot schema matches.
- Otherwise start a new scan; notes/todos hydrated from the run dir still carry over context manually.
Example fix
# before
$ strix resume scan1 # agents.json has no root agent (parent=None)
# after
$ python -c "import json;s=json.load(open('strix_runs/scan1/agents.json'));print([k for k,v in s.get('parent_of',{}).items() if v is None])"
# [] -> snapshot is incomplete; start a fresh scan instead Defensive patterns
Strategy: validation
Validate before calling
import json, pathlib
snap = json.loads((pathlib.Path(run_dir) / 'agents.json').read_text())
has_root = any(p is None for p in snap.get('parent_of', {}).values())
if not has_root:
print('snapshot has no root agent; cannot resume — start a fresh scan') Type guard
def snapshot_has_root(run_dir: str) -> bool:
import json, pathlib
s = json.loads((pathlib.Path(run_dir) / 'agents.json').read_text())
return any(p is None for p in s.get('parent_of', {}).values()) Try / catch
try:
await run_strix_scan(..., is_resume=True)
except RuntimeError as exc:
if 'no root agent' in str(exc):
start_fresh_scan_with_notes_from(run_dir) # manual context carry-over
else:
raise Prevention
- Never delete entries from agents.json.
- Resume with the same Strix version that wrote the snapshot.
When it happens
Trigger: Resuming from a hand-edited agents.json where the root entry was removed; a snapshot written by an older/different schema that serializes parentage differently (all agents report a parent); corrupted-but-parseable JSON that dropped the root record.
Common situations: Manual surgery on run artifacts; version skew between the Strix that wrote the snapshot and the one resuming; snapshots from aborted first-runs that never spawned the root correctly.
Related errors
- extra_system_prompt_context cannot override built-in scope k
- Cannot resume scan {scan_id}: agents.json is unreadable: {ex
- Cannot resume scan {scan_id}: missing SDK session database a
- Invalid target '{target}': {e}
- Invalid API spec '{target}': {exc}
AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15).
Data as JSON: /api/errors/b26fdb769fe94766.
Report an issue: GitHub.