shareAI-lab/learn-claude-code · error · ValueError
Task {task_id} not found
Error message
Task {task_id} not found What it means
Raised by TaskManager._load() in agents/s07_task_system.py:60 when a task JSON file for the given id does not exist under tasks_dir. Ids map 1:1 to files task_<id>.json; _max_id() bootstraps the next id from existing filenames at startup, so any get/update/remove call with an id that was never created — or whose file was deleted externally — fails here.
Source
Thrown at agents/s07_task_system.py:60
SYSTEM = f"You are a coding agent at {WORKDIR}. Use task tools to plan and track work."
# -- TaskManager: CRUD with dependency graph, persisted as JSON files --
class TaskManager:
def __init__(self, tasks_dir: Path):
self.dir = tasks_dir
self.dir.mkdir(exist_ok=True)
self._next_id = self._max_id() + 1
def _max_id(self) -> int:
ids = [int(f.stem.split("_")[1]) for f in self.dir.glob("task_*.json")]
return max(ids) if ids else 0
def _load(self, task_id: int) -> dict:
path = self.dir / f"task_{task_id}.json"
if not path.exists():
raise ValueError(f"Task {task_id} not found")
return json.loads(path.read_text())
def _save(self, task: dict):
path = self.dir / f"task_{task['id']}.json"
path.write_text(json.dumps(task, indent=2, ensure_ascii=False))
def create(self, subject: str, description: str = "") -> str:
task = {
"id": self._next_id, "subject": subject, "description": description,
"status": "pending", "blockedBy": [], "owner": "",
}
self._save(task)
self._next_id += 1
return json.dumps(task, indent=2, ensure_ascii=False)
def get(self, task_id: int) -> str:
return json.dumps(self._load(task_id), indent=2, ensure_ascii=False)
View on GitHub (pinned to 985456f4ad)
Solutions
- Call task_list/task_next first and use ids from its output, never guessed ids
- After wiping or moving the tasks dir, restart the conversation or re-create tasks — old ids are invalid
- Treat this error as terminal for that id: do not retry the same id; pick an existing one
Example fix
# before
tasks.update(task_id=7, status="in_progress")
# ValueError: Task 7 not found
# after
existing = json.loads(tasks.list())
ids = [t["id"] for t in existing if t["status"] == "pending"]
if ids:
tasks.update(task_id=ids[0], status="in_progress") Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def task_exists(tasks_dir: Path, task_id: int) -> bool:
return (tasks_dir / f"task_{task_id}.json").exists()
# before get/update:
assert task_exists(TASKS_DIR, task_id), f"Task {task_id} not found; call task_list for valid ids" Type guard
def is_valid_task_id(task_id: object, tasks_dir) -> bool:
if not isinstance(task_id, int) or isinstance(task_id, bool) or task_id < 1:
return False
return (tasks_dir / f"task_{task_id}.json").exists() Try / catch
try:
TASKS.update(task_id, status)
except ValueError as e:
if "not found" in str(e):
valid = TASKS.list()
return f"Task {task_id} no longer exists. Current tasks:\n{valid}"
raise Prevention
- Always call task_list first and use ids from its output
- Never guess or extrapolate ids; they are file-backed, not generated
- If you wipe the tasks dir, invalidate every id held in conversation/memory
When it happens
Trigger: Calling task_get/task_update with a guessed or stale id (e.g. after the tasks dir was wiped between runs, so old ids no longer exist), a deleted task, or an id larger than the max seen by list_tasks(). Note _max_id() does int(f.stem.split("_")[1]) without a try/except here, so a manually created task file with a non-numeric suffix would crash earlier at startup rather than here.
Common situations: Agent resumes a session with persisted conversation but a cleaned tasks dir. Model hallucinates an id instead of calling task_list first. Two harness instances sharing one tasks_dir racing on file deletion.
Related errors
- Task {task_id} not found
- Invalid status: {status}
- Invalid status: {status}
- Max 20 todos allowed
- Item {item_id}: text required
AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14).
Data as JSON: /api/errors/14de6dd5eabe3661.
Report an issue: GitHub.