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

  1. Inspect agents.json in the run directory (strix_runs/<run>/agents.json): validate it with `python -m json.tool` and check permissions.
  2. If it is truncated/corrupt beyond repair, start a fresh scan instead of resuming — artifacts in the run dir are still readable for reporting.
  3. Restore agents.json from a backup of the run directory if one exists.
  4. 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

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


AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15). Data as JSON: /api/errors/9ebc9550fe8db59a. Report an issue: GitHub.