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

Dependency not found

Error message

Dependency not found: {dependency}

What it means

Raised by TaskStore.create() in s10_task_system/code.py:109 when a dependency listed in blocked_by does not exist as a task file in the store. Before creating a task, create() de-duplicates the blocked_by list and calls self.exists(dependency) for each entry, which resolves '{dependency}.json' under the store root. Any missing or malformed dependency ID aborts creation, preserving the invariant that blockedBy references are always live tasks.

Solutions

  1. Verify each dependency with store.exists(dep) before create(), and drop or resolve missing ones explicitly.
  2. Re-derive dependency IDs at runtime (e.g. look tasks up by subject with store.list()) instead of caching IDs across sessions.
  3. If a referenced task vanished legitimately, recreate it first or create the new task without that dependency.

Example fix

# before
store.create('ship release', blocked_by=['task_deadbeef', 'task_00000000'])

# after
blocked = [d for d in ['task_deadbeef', 'task_00000000'] if store.exists(d)]
store.create('ship release', blocked_by=blocked)
Defensive patterns

Strategy: validation

Validate before calling

def missing_deps(store, blocked_by):
    return [d for d in (blocked_by or []) if not store.exists(d)]

Try / catch

try:
    store.create(subject, blocked_by=deps)
except ValueError as e:
    if str(e).startswith('Dependency not found'):
        deps = [d for d in deps if store.exists(d)]
        store.create(subject, blocked_by=deps)
    else:
        raise

Prevention

When it happens

Trigger: Calling store.create('x', blocked_by=['task_00000000']) when no such file exists; passing a dependency ID with a typo or wrong length; passing a bg_ or cron_ ID from a different subsystem; referencing a task that was deleted after you copied its ID. Note the dependency must also match the task_ ID pattern or exists() itself raises 'Invalid task ID'.

Common situations: Scripts that hardcode dependency IDs from a previous run in a fresh store; UIs offering a task picker fed by stale data; concurrent deletion racing with creation; multi-agent flows where one agent creates tasks referencing another agent's store.

Related errors


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

Appendix: source

Thrown at s10_task_system/code.py:109

        root = self._root(create=create_root)
        path = (root / f"{task_id}.json").resolve()
        if not path.is_relative_to(root):
            raise ValueError(f"Invalid task ID: {task_id!r}")
        return path

    def exists(self, task_id: str) -> bool:
        return self._path(task_id).is_file()

    def create(self, subject: str, description: str = "",
               blocked_by: list[str] | None = None) -> Task:
        subject = subject.strip()
        if not subject:
            raise ValueError("Task subject cannot be empty")

        dependencies = list(dict.fromkeys(blocked_by or []))
        for dependency in dependencies:
            if not self.exists(dependency):
                raise ValueError(f"Dependency not found: {dependency}")

        self._root(create=True)
        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 self._path(task.id, create_root=True).open(
                    "x", encoding="utf-8"
                ) as handle:
                    json.dump(asdict(task), handle, indent=2)
                return task
            except FileExistsError:

View on GitHub (pinned to 985456f4ad)