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

Task {tid} not found

Error message

Task {tid} not found

What it means

Raised by TaskManager._load in s_full.py when no file task_{tid}.json exists in TASKS_DIR. Every task operation (get, update status, assign owner, etc.) loads through _load, so any reference to a deleted or never-created id fails here. Ids are assigned by scanning existing files (max id + 1), so gaps from deleted tasks are never reused and those ids fail permanently.

Source

Thrown at agents/s_full.py:272

    )
    summary = resp.content[0].text
    return [
        {"role": "user", "content": f"[Compressed. Transcript: {path}]\n{summary}"},
    ]


# === SECTION: file_tasks (s07) ===
class TaskManager:
    def __init__(self):
        TASKS_DIR.mkdir(exist_ok=True)

    def _next_id(self) -> int:
        ids = [int(f.stem.split("_")[1]) for f in TASKS_DIR.glob("task_*.json")]
        return max(ids, default=0) + 1

    def _load(self, tid: int) -> dict:
        p = TASKS_DIR / f"task_{tid}.json"
        if not p.exists(): raise ValueError(f"Task {tid} not found")
        return json.loads(p.read_text())

    def _save(self, task: dict):
        (TASKS_DIR / f"task_{task['id']}.json").write_text(json.dumps(task, indent=2))

    def create(self, subject: str, description: str = "") -> str:
        task = {"id": self._next_id(), "subject": subject, "description": description,
                "status": "pending", "owner": None, "blockedBy": []}
        self._save(task)
        return json.dumps(task, indent=2)

    def get(self, tid: int) -> str:
        return json.dumps(self._load(tid), indent=2)

    def update(self, tid: int, status: str = None,
               add_blocked_by: list = None, remove_blocked_by: list = None) -> str:
        task = self._load(tid)
        if status:

View on GitHub (pinned to 985456f4ad)

Solutions

  1. Always use the id returned from tasks.create() and thread it through the flow verbatim
  2. Before acting, verify existence via the list tool or TASKS_DIR glob rather than assuming
  3. If the tasks directory was reset, recreate the task and update stored references to the new id
  4. Catch ValueError at the tool boundary and re-list tasks so the agent can self-correct

Example fix

// before
tasks.get(42)  # never created
// after
t = tasks.create(subject="Fix login", description="...")
tasks.get(t["id"])
Defensive patterns

Strategy: validation

Validate before calling

def task_exists(tid: int) -> bool:
    return (TASKS_DIR / f"task_{tid}.json").exists()

if not task_exists(tid):
    t = TASKS.create(subject=fallback_subject)
    tid = t['id']
result = TASKS.get(tid)

Try / catch

try:
    TASKS.get(tid)
except ValueError as e:
    if 'not found' in str(e):
        tasks = TASKS.list()
        # pick or recreate the right task, then retry
    else:
        raise

Prevention

When it happens

Trigger: Calling tasks.get(5) when task_5.json was never created or was deleted; reusing an id captured in an earlier session after the tasks directory was reset; passing a task id hallucinated by an LLM instead of one returned by create().

Common situations: Agent flows that guess ids; persisted plans referencing tasks across a workspace reset that wiped TASKS_DIR; races where cleanup deletes a task between listing and acting on it.

Related errors


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