usestrix/strix · error · RuntimeError
Cannot resume scan {scan_id}: agents.json is unreadable: {ex
Error message
Cannot resume scan {scan_id}: agents.json is unreadable: {exc} What it means
Raised on the resume path of run_strix_scan (strix/core/runner.py:194) when the run directory's agents.json snapshot cannot be read as UTF-8 text (OSError) or does not parse as JSON (JSONDecodeError). The snapshot holds the agent-graph state needed to restore the coordinator, so a corrupt or missing file makes resumption impossible; the original exception is chained via `from exc`.
Source
Thrown at strix/core/runner.py:194
logger.info("LLM model resolved: %s", resolved_model)
chat_completions_tools = uses_chat_completions_tool_schema(resolved_model, settings)
if coordinator is None:
coordinator = AgentCoordinator()
coordinator.set_snapshot_path(agents_path)
from strix.tools.notes.tools import hydrate_notes_from_disk
from strix.tools.todo.tools import hydrate_todos_from_disk
hydrate_todos_from_disk(state_dir)
hydrate_notes_from_disk(state_dir)
root_id: str | None = None
if is_resume:
try:
snap = json.loads(agents_path.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError) as exc:
raise RuntimeError(
f"Cannot resume scan {scan_id}: agents.json is unreadable: {exc}",
) from exc
if not agents_db.exists():
raise RuntimeError(
f"Cannot resume scan {scan_id}: missing SDK session database at {agents_db}",
)
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,View on GitHub (pinned to 8551339130)
Solutions
- Inspect agents.json in the run directory (strix_runs/<run>/agents.json): validate it with `python -m json.tool` and check permissions.
- If it is truncated/corrupt beyond repair, start a fresh scan instead of resuming — artifacts in the run dir are still readable for reporting.
- Restore agents.json from a backup of the run directory if one exists.
- Prevent recurrence: avoid force-killing strix mid-scan; use graceful stop so snapshots flush.
Example fix
# before $ strix resume my-scan # RuntimeError: agents.json is unreadable # after $ python -m json.tool strix_runs/my-scan/agents.json # locate the syntax error $ strix -n -t ./ --run-name my-scan-2 # or start fresh
Defensive patterns
Strategy: validation
Validate before calling
import json, pathlib
snap_path = pathlib.Path(run_dir) / 'agents.json'
try:
json.loads(snap_path.read_text(encoding='utf-8'))
except (OSError, json.JSONDecodeError) as exc:
print(f'cannot resume: snapshot bad ({exc}); start a new scan') Type guard
def snapshot_is_resumable(run_dir: str) -> bool:
import json, pathlib
p = pathlib.Path(run_dir) / 'agents.json'
try:
json.loads(p.read_text(encoding='utf-8'))
except (OSError, json.JSONDecodeError):
return False
return True Try / catch
try:
await run_strix_scan(..., is_resume=True)
except RuntimeError as exc:
if 'agents.json is unreadable' in str(exc):
# fall back to a fresh run; old artifacts remain readable
await run_strix_scan(..., is_resume=False)
else:
raise Prevention
- Stop scans gracefully so snapshots flush fully.
- Back up the run directory before resuming.
- Never hand-edit agents.json.
When it happens
Trigger: Calling run_strix_scan(resume=True) / strix resume <scan_id> when agents.json was truncated by a crash or disk-full, edited by hand, saved with invalid JSON, or has unreadable permissions.
Common situations: Killing the strix process (or a power loss) mid-write of agents.json; syncing run directories through tools that mangle encoding; running as a different user with weaker file permissions.
Related errors
- Cannot resume scan {scan_id}: missing SDK session database a
- vulnerabilities.json at {path} is corrupt ({exc}); refusing
- bad_response
- Cannot resume scan {scan_id}: agents.json has no root agent
- Path exists but is not a directory: {target}
AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15).
Data as JSON: /api/errors/9ebc9550fe8db59a.
Report an issue: GitHub.