mvanhorn/last30days-skill · error · HandoffContractError
Could not read {label} file {file_path}: {exc}
Error message
Could not read {label} file {file_path}: {exc} What it means
`_load_host_file` (reader for host-authored handoff files: the leg-2 `--judgments` file and leg-3 `--angles` file) raises HandoffContractError when `Path(path).expanduser().read_text()` raises OSError — the file does not exist, is unreadable, or the path is invalid. Unlike the engine-written artifacts, this file is authored by the host/user, so the common case is simply a wrong path or missing file. The message includes the label ('judgments'/'angles'), the expanded path, and the OS error; the CLI maps it to exit 2.
Source
Thrown at skills/last30days/scripts/lib/discovery_handoff.py:621
return PendingReport(
schema_version=str(version),
bundle_id=bundle_id,
generated_at=str(generated_at or ""),
run_ref=str(payload.get("run_ref") or ""),
report=report,
angle_inputs=angle_inputs,
mock=bool(payload.get("mock")),
path=path,
)
def _load_host_file(path: str | Path, label: str) -> dict[str, Any]:
"""Load a host-authored handoff file with strict top-level checks."""
file_path = Path(path).expanduser()
try:
raw = file_path.read_text(encoding="utf-8")
except OSError as exc:
raise HandoffContractError(
f"Could not read {label} file {file_path}: {exc}"
) from exc
try:
payload = json.loads(raw)
except json.JSONDecodeError as exc:
raise HandoffContractError(
f"{label.capitalize()} file {file_path} is not valid JSON: {exc}"
) from exc
if not isinstance(payload, dict):
raise HandoffContractError(
f"{label.capitalize()} file {file_path} must be a top-level JSON "
f"object, got {type(payload).__name__}."
)
return payload
def _require_bundle_binding(
payload: dict[str, Any],View on GitHub (pinned to c7460f6114)
Solutions
- Verify the path exactly as printed in the message with `ls -l` (the message shows the expanded path).
- Use an absolute path for `--judgments` / `--angles` to eliminate cwd ambiguity.
- Confirm the file was actually saved/written by the authoring step before invoking the leg.
- If permissions are the issue, `chmod +r <file>`.
Example fix
# before python3 last30days.py "topic" --discover --judgments judgemnets.json # typo # after python3 last30days.py "topic" --discover --judgments /abs/path/judgments.json
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def host_file_ready(path_str: str) -> Path:
p = Path(path_str).expanduser().resolve()
if not p.is_file():
raise SystemExit(f"{p} does not exist; author the file first")
return p Try / catch
from lib import discovery_handoff
try:
payload = discovery_handoff._load_host_file("judgments.json", "judgments")
except discovery_handoff.HandoffContractError as exc:
if "Could not read" in exc.message:
# wrong path or permissions; the message shows the expanded path
... Prevention
- Pass absolute paths to --judgments / --angles.
- Assert the file exists and is non-empty in your wrapper before invoking the leg.
- Save-and-close editor buffers before running; unsaved files are the #1 cause.
When it happens
Trigger: `--judgments missing.json` (typo'd filename); passing a directory instead of a file; permissions denying read; a `~`-relative path that fails to expand to a real file.
Common situations: Authoring judgments in an editor and never saving; running the CLI from a different cwd with a relative path; host harnesses writing the file to an unexpected location; quoting mistakes leaving a literal `~` unexpanded by the shell (here expanduser() handles it, but a wrong username like `~other/file` may not exist).
Related errors
- No handoff location available to write the nominations bundl
- Could not write nominations bundle {path}: {exc}
- Could not read {label.lower()} {path}: {exc}
- {label.capitalize()} file {file_path} is not valid JSON: {ex
- No discovery nominations bundle found. Searched:\n{_searched
AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15).
Data as JSON: /api/errors/16f94997373b1789.
Report an issue: GitHub.