mvanhorn/last30days-skill · error · HandoffContractError

No pending discovery report found. Searched:\n{_searched_lin

Error message

No pending discovery report found. Searched:\n{_searched_lines(searched)}\n{_RESUME_REMEDY}

What it means

`load_pending_report` raises HandoffContractError (exit 2) when no `discover-pending.json` exists in any searched location — save dir when `--save-dir` was supplied, else the config dir, never a cross-store fallback. The pending report is leg-2 output that leg 3 (`--discover --finalize`) finalizes, so its absence means leg 2 never ran (or ran into a different store). The message names the searched paths and prescribes the resume remedy: re-run `--discover --judgments <file>`, or restart the whole protocol if the bundle is stale too.

Source

Thrown at skills/last30days/scripts/lib/discovery_handoff.py:567

def read_pending_report(
    *,
    save_dir: str | Path | None = None,
    config_dir: Path | None = None,
) -> PendingReport:
    """Locate and parse the leg-2 pending report for the finalize leg.

    Same strictness family as the bundle reader: missing file (the searched
    location named - save dir when supplied, else config dir, never a
    cross-store fallback), unreadable, invalid JSON, wrong kind or schema version,
    missing bundle_id, or stale TTL all raise HandoffContractError (mapped to
    exit 2 by the CLI layer). Staleness is measured from the PENDING report's
    own generated_at - the leg-2 write started a fresh authoring window - and
    the remedy is the resume leg, not a full re-sweep.
    """
    searched = _search_paths(save_dir, config_dir, pending_report_path)
    path = next((candidate for candidate in searched if candidate.exists()), None)
    if path is None:
        raise HandoffContractError(
            "No pending discovery report found. Searched:\n"
            f"{_searched_lines(searched)}\n{_RESUME_REMEDY}"
        )
    return _parse_pending_file(path)


def _parse_pending_file(path: Path) -> PendingReport:
    payload, bundle_id, generated_at = _parse_handoff_envelope(
        path,
        label="Pending discovery report",
        kind=schema.DISCOVERY_PENDING_KIND,
        schema_version=schema.DISCOVERY_PENDING_SCHEMA_VERSION,
        remedy=_RESUME_REMEDY,
        missing_id_context="angles cannot bind to it",
        stale_context="the judged window it captured has moved on",
    )
    version = payload.get("schema_version")
    report = payload.get("report")

View on GitHub (pinned to c7460f6114)

Solutions

  1. Run leg 2 first (`--discover --judgments <file>`) with the SAME `--save-dir` (or config dir) you will use for `--finalize`.
  2. Confirm `discover-pending.json` exists in the path listed under 'Searched:'.
  3. If leg 2 failed earlier, fix that failure first (its bundle errors surface as errors 25-34), then re-run it.
  4. If more than an hour passed, expect staleness next (error 32): budget to re-run the resume leg rather than the full sweep.

Example fix

# before
python3 last30days.py "topic" --discover --finalize --save-dir /tmp/run   # leg 2 never ran here
# after
python3 last30days.py "topic" --discover --judgments judgments.json --save-dir /tmp/run && python3 last30days.py "topic" --discover --finalize --angles angles.json --save-dir /tmp/run
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
from lib.discovery_handoff import pending_report_path, handoff_state_dir

state = handoff_state_dir(save_dir, config_dir)
if state is None or not pending_report_path(state).exists():
    raise SystemExit("no pending report: run `--discover --judgments <file>` first in this store")

Try / catch

from lib import discovery_handoff
try:
    pending = discovery_handoff.load_pending_report(save_dir=save_dir, config_dir=config_dir)
except discovery_handoff.HandoffContractError as exc:
    sys.stderr.write(exc.message + "\n")
    sys.exit(2)

Prevention

When it happens

Trigger: Running `--discover --finalize [--angles <file>]` before completing leg 2; running leg 2 with `--save-dir A` and leg 3 with a different or absent save dir; the pending file deleted or never written because leg 2 failed.

Common situations: Sessions split across days/directories where leg 2 happened elsewhere; agents attempting to finalize straight from a bundle; save-dir typos between invocations.

Related errors


AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15). Data as JSON: /api/errors/eaac299acef78fdf. Report an issue: GitHub.