usestrix/strix · critical · RuntimeError

vulnerabilities.json at {path} is corrupt ({exc}); refusing

Error message

vulnerabilities.json at {path} is corrupt ({exc}); refusing to start fresh — that would overwrite prior vulnerability MDs on disk. Inspect or delete the run dir.

What it means

ReportState hydrates itself from a run directory on startup. If vulnerabilities.json exists but cannot be read or parsed (OSError or JSONDecodeError), it raises RuntimeError instead of silently starting with an empty state. The explicit rationale: starting fresh would overwrite previously written vulnerability Markdown files on disk, so the corrupt file must be resolved by the operator first.

Source

Thrown at strix/report/state.py:198

        if data:
            self.run_record.update(data)
            if isinstance(data.get("start_time"), str):
                self.start_time = data["start_time"]
            if isinstance(data.get("end_time"), str):
                self.end_time = data["end_time"]
            scan_results = data.get("scan_results")
            if isinstance(scan_results, dict):
                self.scan_results = scan_results
                self.final_scan_result = self._format_final_scan_result(scan_results)
            self._hydrate_llm_usage(data.get("llm_usage"))
            logger.info("report state hydrated run.json from %s", run_dir)

        json_path = run_dir / "vulnerabilities.json"
        if json_path.exists():
            try:
                data = json.loads(json_path.read_text(encoding="utf-8"))
            except (OSError, json.JSONDecodeError) as exc:
                raise RuntimeError(
                    f"vulnerabilities.json at {json_path} is corrupt ({exc}); "
                    f"refusing to start fresh — that would overwrite prior "
                    f"vulnerability MDs on disk. Inspect or delete the run dir.",
                ) from exc
            if not isinstance(data, list):
                raise RuntimeError(
                    f"vulnerabilities.json at {json_path} is not a list",
                )
            self.vulnerability_reports = [r for r in data if isinstance(r, dict)]
            for r in self.vulnerability_reports:
                rid = r.get("id")
                if isinstance(rid, str):
                    self._saved_vuln_ids.add(rid)
            logger.info(
                "report state hydrated %d vulnerability report(s)",
                len(self.vulnerability_reports),
            )

View on GitHub (pinned to 8551339130)

Solutions

  1. Inspect vulnerabilities.json in the named run dir — if it is a truncated tail, salvage valid entries or delete the file, then retry.
  2. If the run is disposable, delete the whole run directory and start a new scan.
  3. Restore the file from a backup of the run dir if prior findings matter.
  4. Check for the root cause (disk full, killed process) before retrying so the new write does not corrupt again.
Defensive patterns

Strategy: validation

Validate before calling

import json
from pathlib import Path

def vuln_json_loadable(run_dir: Path) -> bool:
    p = run_dir / "vulnerabilities.json"
    if not p.exists():
        return True
    try:
        json.loads(p.read_text(encoding="utf-8"))
        return True
    except (OSError, json.JSONDecodeError):
        return False

Try / catch

try:
    state = ReportState(run_dir)
except RuntimeError as exc:
    if "vulnerabilities.json" in str(exc) and "corrupt" in str(exc):
        # operator decision required — do NOT auto-delete; prior MDs are at stake
        raise
    raise

Prevention

When it happens

Trigger: Resuming or viewing a run whose strix_runs/<run>/vulnerabilities.json is truncated (e.g. process killed mid atomic-write, disk full) or unreadable (permissions, removed while reading). Any code path that constructs ReportState over that run dir (resume, viewer, report regeneration) triggers it.

Common situations: Scan process killed or OOM during a write; non-atomic external edits to the file; partial copy/sync of the run directory; filesystem permission changes between runs.

Related errors


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