{"record":{"id":"36bcd21c1dfc06c0","repo":"shareAI-lab/learn-claude-code","slug":"task-tid-not-found","errorCode":null,"errorMessage":"Task {tid} not found","messagePattern":"Task (.+?) not found","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agents/s_full.py","lineNumber":272,"sourceCode":"    )\n    summary = resp.content[0].text\n    return [\n        {\"role\": \"user\", \"content\": f\"[Compressed. Transcript: {path}]\\n{summary}\"},\n    ]\n\n\n# === SECTION: file_tasks (s07) ===\nclass TaskManager:\n    def __init__(self):\n        TASKS_DIR.mkdir(exist_ok=True)\n\n    def _next_id(self) -> int:\n        ids = [int(f.stem.split(\"_\")[1]) for f in TASKS_DIR.glob(\"task_*.json\")]\n        return max(ids, default=0) + 1\n\n    def _load(self, tid: int) -> dict:\n        p = TASKS_DIR / f\"task_{tid}.json\"\n        if not p.exists(): raise ValueError(f\"Task {tid} not found\")\n        return json.loads(p.read_text())\n\n    def _save(self, task: dict):\n        (TASKS_DIR / f\"task_{task['id']}.json\").write_text(json.dumps(task, indent=2))\n\n    def create(self, subject: str, description: str = \"\") -> str:\n        task = {\"id\": self._next_id(), \"subject\": subject, \"description\": description,\n                \"status\": \"pending\", \"owner\": None, \"blockedBy\": []}\n        self._save(task)\n        return json.dumps(task, indent=2)\n\n    def get(self, tid: int) -> str:\n        return json.dumps(self._load(tid), indent=2)\n\n    def update(self, tid: int, status: str = None,\n               add_blocked_by: list = None, remove_blocked_by: list = None) -> str:\n        task = self._load(tid)\n        if status:","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/shareAI-lab/learn-claude-code/blob/985456f4adea6f4df8fbad4112245dbd97444eae/agents/s_full.py#L254-L290","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","solutions":["Always use the id returned from tasks.create() and thread it through the flow verbatim","Before acting, verify existence via the list tool or TASKS_DIR glob rather than assuming","If the tasks directory was reset, recreate the task and update stored references to the new id","Catch ValueError at the tool boundary and re-list tasks so the agent can self-correct"],"exampleFix":"// before\ntasks.get(42)  # never created\n// after\nt = tasks.create(subject=\"Fix login\", description=\"...\")\ntasks.get(t[\"id\"])","handlingStrategy":"validation","validationCode":"def task_exists(tid: int) -> bool:\n    return (TASKS_DIR / f\"task_{tid}.json\").exists()\n\nif not task_exists(tid):\n    t = TASKS.create(subject=fallback_subject)\n    tid = t['id']\nresult = TASKS.get(tid)","typeGuard":null,"tryCatchPattern":"try:\n    TASKS.get(tid)\nexcept ValueError as e:\n    if 'not found' in str(e):\n        tasks = TASKS.list()\n        # pick or recreate the right task, then retry\n    else:\n        raise","preventionTips":["Thread ids returned by create() through the entire flow","Never construct ids from model guesses","After resetting the tasks dir, invalidate all cached task references"],"tags":["task-management","not-found","persistence"],"backgroundTag":null,"analyzedSha":"985456f4adea6f4df8fbad4112245dbd97444eae","analyzedAt":"2026-08-14T22:02:26.028Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}