shareAI-lab/learn-claude-code · error · WorkflowInputError

resume journal not found for

Error message

resume journal not found for {run_id}

What it means

WorkflowJournal(resume=True) requires an existing <store>/<runId>.journal.jsonl to replay cached agent() results from. If the file does not exist, WorkflowInputError is raised — you cannot resume a run that never started or whose store was lost. The check happens before the journal is opened, so nothing is created or truncated on failure.

Solutions

  1. Verify the file exists first: (STORE / f"{run_id}.journal.jsonl").exists()
  2. Ensure STORE resolves to the same absolute path across processes/environments
  3. If the journal is gone, start a fresh run with reserve_run_id instead of resuming

Example fix

# before
result = resume(workflow, run_id=saved_id)  # journal deleted

# after
if (STORE / f"{saved_id}.journal.jsonl").exists():
    result = resume(workflow, run_id=saved_id)
else:
    result = run(workflow, run_id=reserve_run_id(meta))
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

def journal_exists(store: Path, run_id: str) -> bool:
    return (store / f"{run_id}.journal.jsonl").exists()

if not journal_exists(STORE, run_id):
    run_id = reserve_run_id(meta)  # fall back to a fresh run
result = resume(workflow, run_id=run_id)

Type guard

def is_resumable(store: Path, run_id: str) -> bool:
    return (store / f"{run_id}.journal.jsonl").is_file()

Try / catch

try:
    result = resume(workflow, run_id=run_id)
except WorkflowInputError as exc:
    if "resume journal not found" in str(exc):
        result = run(workflow, run_id=reserve_run_id(meta))
    else:
        raise

Prevention

When it happens

Trigger: resume(run_id) with a typo'd or hand-edited id. Resuming after the store directory was deleted, moved, or STORE was redefined (different path between runs). Resuming a run that crashed before its first journal write (the file is created on open, but a run reserved then aborted may only have <runId>.json).

Common situations: Store path configured per environment (local vs CI vs container volume) so the journal lives elsewhere. Cleanup jobs pruning 'old' .jsonl files. Run ids persisted in a DB but the file store is ephemeral.

Related errors


AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14). Data as JSON: /api/errors/5b0454893a8f140c. Report an issue: GitHub.

Appendix: source

Thrown at s16_workflow_runtime/code.py:333


RUNNER_FACTORY = MockAgentRunner


# -- Journal --
class WorkflowJournal:
    """Append-only <runId>.journal.jsonl. On resume, agent() calls whose
    semantic key is already present are replayed from cache instead of re-run."""

    def __init__(self, run_id, resume, store=None):
        store = STORE if store is None else store
        store.mkdir(parents=True, exist_ok=True)
        self.path = store / f"{run_id}.journal.jsonl"
        self.resume = resume
        self.cache = {}
        if resume:
            if not self.path.exists():
                raise WorkflowInputError(f"resume journal not found for {run_id}")
            for line_number, line in enumerate(self.path.read_text().splitlines(), start=1):
                try:
                    rec = json.loads(line)
                    if (
                        not isinstance(rec, dict)
                        or not isinstance(rec.get("key"), str)
                        or "value" not in rec
                    ):
                        raise ValueError("expected key/value record")
                except (json.JSONDecodeError, ValueError) as exc:
                    raise WorkflowInputError(
                        f"invalid resume journal record at line {line_number}"
                    ) from exc
                self.cache[rec["key"]] = rec["value"]
            self._f = self.path.open("a")
        else:
            self._f = self.path.open("w")             # fresh run truncates

View on GitHub (pinned to 985456f4ad)