shareAI-lab/learn-claude-code · critical · RuntimeError

Could not allocate a unique task ID

Error message

Could not allocate a unique task ID

What it means

create_task() tries up to 100 times to allocate an ID whose file does not yet exist, using exclusive open('x'). With an 8-hex-char space (4 billion IDs) this is practically unreachable unless the filesystem misreports FileExistsError for every candidate — e.g. the .tasks directory is not writable in a way that surfaces as FileExistsError, or something (antivirus, sync client, a stuck .tmp naming scheme) creates files matching every probe.

Source

Thrown at s13_agent_teams/code.py:158

        for dependency in dependencies:
            if not _task_path(dependency).is_file():
                raise ValueError(f"Dependency not found: {dependency}")
        for _ in range(100):
            task = Task(
                id=f"task_{secrets.token_hex(4)}",
                subject=subject,
                description=description,
                status="pending",
                owner=None,
                blockedBy=dependencies,
            )
            try:
                with _task_path(task.id).open("x", encoding="utf-8") as handle:
                    json.dump(asdict(task), handle, indent=2)
                return task
            except FileExistsError:
                continue
    raise RuntimeError("Could not allocate a unique task ID")


def save_task(task: Task):
    with task_store_lock():
        path = _task_path(task.id)
        temporary = path.with_name(
            f".{path.name}.{os.getpid()}.{threading.get_ident()}.tmp"
        )
        try:
            temporary.write_text(
                json.dumps(asdict(task), indent=2), encoding="utf-8"
            )
            os.replace(temporary, path)
        finally:
            temporary.unlink(missing_ok=True)


def load_task(task_id: str) -> Task:

View on GitHub (pinned to 985456f4ad)

Solutions

  1. Check .tasks for tens of thousands of task files or foreign files matching task_*.json and clean up.
  2. Verify the workspace filesystem supports O_EXCL properly (local disk vs FUSE/network mount); move the workspace local.
  3. If genuinely at capacity, widen the ID (token_hex(8)) and update TASK_ID_PATTERN.
Defensive patterns

Strategy: retry

Validate before calling

import os, stat

def tasks_dir_writable_exclusive(tasks_dir) -> bool:
    try:
        if not tasks_dir.exists():
            return False
        probe = tasks_dir / '.probe_exclusive'
        fd = os.open(probe, os.O_CREAT | os.O_EXCL | os.O_WRONLY)
        os.close(fd); probe.unlink()
        return True
    except OSError:
        return False

Try / catch

for attempt in range(3):
    try:
        return create_task(subject, blockedBy=deps)
    except RuntimeError as exc:
        if 'unique task ID' not in str(exc) or attempt == 2:
            raise
        time.sleep(0.05 * (attempt + 1))

Prevention

When it happens

Trigger: 100 consecutive collisions of secrets.token_hex(4); or the exclusive-create call failing with FileExistsError for unrelated filesystem reasons (read-only or corrupted directory mapped to that errno by a FUSE mount).

Common situations: Essentially never in normal use. Seen with exotic filesystems (network/FUSE mounts) that return EEXIST for failed creates, or in fault-injection tests.

Related errors


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