shareAI-lab/learn-claude-code · error · WorkflowInputError
could not allocate a unique workflow runId
Error message
could not allocate a unique workflow runId
What it means
reserve_run_id tries up to 32 times to create <runId>.json with O_CREAT|O_EXCL (atomic create-if-absent). Every attempt collided with an existing file, so no unique identity could be reserved and WorkflowInputError is raised before any journal is touched. Run ids embed 16 random hex characters (secrets.token_hex(8)), so 32 straight collisions indicate the filesystem or id generation is degenerate rather than bad luck.
Source
Thrown at s16_workflow_runtime/code.py:66
def create_run_id(meta) -> str:
return f"wf_{meta['name']}_{secrets.token_hex(8)}"
def reserve_run_id(meta) -> str:
"""Reserve a fresh run identity before any journal can be truncated."""
STORE.mkdir(parents=True, exist_ok=True)
for _ in range(32):
run_id = validate_run_id(create_run_id(meta))
snapshot_path = STORE / f"{run_id}.json"
try:
fd = os.open(snapshot_path, os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600)
except FileExistsError:
continue
os.close(fd)
return run_id
raise WorkflowInputError("could not allocate a unique workflow runId")
def create_task_id(run_id) -> str:
return f"local_workflow_{run_id}"
def validate_run_id(run_id):
if not isinstance(run_id, str) or not RUN_ID_RE.fullmatch(run_id):
raise WorkflowInputError("invalid workflow runId")
return run_id
# -- Errors --
class WorkflowInputError(Exception):
"""Bad workflow, metadata, or schema input."""
_run_locks_guard = threading.Lock()View on GitHub (pinned to 985456f4ad)
Solutions
- If tests stub secrets.token_hex, ensure the stub yields distinct values per call
- Point STORE at a clean writable directory for the run
- Clear stale <runId>.json placeholder files if a previous run crashed between reservation and journal write
Example fix
# before (test stub breaks uniqueness) monkeypatch.setattr(secrets, "token_hex", lambda n: "deadbeefdeadbeef") # after values = iter(["aa11" * 4, "bb22" * 4]) monkeypatch.setattr(secrets, "token_hex", lambda n: next(values))
Defensive patterns
Strategy: retry
Validate before calling
from pathlib import Path
def store_is_clean(store: Path) -> bool:
# placeholder collisions are the only realistic failure; ensure the dir is writable
return store.is_dir() or store.parent.is_dir()
assert store_is_clean(STORE) Try / catch
for attempt in range(3):
try:
run_id = reserve_run_id(meta)
break
except WorkflowInputError:
if attempt == 2:
raise
# deterministic-id test stub or polluted store; fix the source, then retry Prevention
- Never stub secrets.token_hex with a constant in tests
- Keep STORE clean of stale placeholder .json files
- Treat 32-collision failure as an environment defect, not bad luck
When it happens
Trigger: A monkeypatched or seeded secrets.token_hex in tests returning constant values. A STORE directory pre-populated with files matching wf_<name>_<hex>.json for the exact hex values generated (e.g. replaying a captured id sequence). Filesystem issues where O_EXCL is unsupported and open always reports EEXIST.
Common situations: Test suites that stub randomness without uniqueness. Restoring a store from a snapshot and rerunning with a deterministic RNG. Exotic network filesystems with broken O_EXCL semantics.
Related errors
- invalid workflow runId
- resume journal not found for {run_id}
- resume runId does not match workflow meta
- Invalid memory filename: {filename}
- Memory path escapes the store: {filename}
AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14).
Data as JSON: /api/errors/cd1b8e8e4b2e1cd1.
Report an issue: GitHub.