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

Dependency not found: {dependency}

Error message

Dependency not found: {dependency}

What it means

create_task() validates every entry in blockedBy before writing the new task: each dependency must already exist as a task file in the tasks store. Referencing an unknown dependency would create a permanently unsatisfiable blocker, so it fails fast under the store lock.

Source

Thrown at s15_integrated_harness/code.py:217

    if not isinstance(task_id, str) or not TASK_ID_PATTERN.fullmatch(task_id):
        raise ValueError(f"Invalid task ID: {task_id!r}")
    path = (TASKS_DIR / f"{task_id}.json").resolve()
    if (not TASKS_ROOT.is_relative_to(WORKDIR.resolve())
            or not path.is_relative_to(TASKS_ROOT)):
        raise ValueError(f"Invalid task ID: {task_id!r}")
    return path


def create_task(subject: str, description: str = "",
                blockedBy: list[str] | None = None) -> Task:
    subject = subject.strip()
    if not subject:
        raise ValueError("Task subject cannot be empty")
    dependencies = list(dict.fromkeys(blockedBy or []))
    with task_store_lock():
        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")

View on GitHub (pinned to 985456f4ad)

Solutions

  1. Call list_tasks() first and use exact existing IDs for blockedBy.
  2. Create the dependency task before the task that blocks on it.
  3. Double-check the ID against task_<8 hex chars> format — a typo is the most common cause.

Example fix

// before
create_task("Ship release", blockedBy=["task_00000000"])

// after
existing = {t.id for t in list_tasks()}
deps = [d for d in ["task_0f1e2d3c"] if d in existing]
create_task("Ship release", blockedBy=deps)
Defensive patterns

Strategy: validation

Validate before calling

existing = {t.id for t in list_tasks()}
missing = [d for d in blockedBy if d not in existing]
if missing:
    raise ValueError(f"Unknown dependencies: {missing}")
task = create_task(subject, description, blockedBy=blockedBy)

Type guard

def deps_exist(deps, existing_ids) -> bool:
    return all(d in existing_ids for d in deps)

Try / catch

try:
    create_task(subject, description, blockedBy=deps)
except ValueError as e:
    if "Dependency not found" in str(e):
        deps = [d for d in deps if d in {t.id for t in list_tasks()}]
        # re-ask or create missing deps, then retry once

Prevention

When it happens

Trigger: Calling create_task(blockedBy=["task_deadbeef"]) where that file does not exist in TASKS_DIR; using an ID from a different workspace; a typo or truncated ID; a dependency that was deleted between listing and creating (TOCTOU window closed by the lock check).

Common situations: Agent invents a dependency ID instead of reading list_tasks(); tasks directory reset/cleaned while a session holds old IDs; copy-pasting IDs across environments.

Related errors


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