shareAI-lab/learn-claude-code · error · ValueError
Task file ID does not match {task_id}
Error message
Task file ID does not match {task_id} What it means
load_task() reads <task_id>.json, deserializes it into a Task, and verifies the JSON's internal 'id' field equals the filename stem. A mismatch means the file was renamed, hand-edited, or copied without updating its contents — the store's filename/content invariant is broken, so the record is rejected rather than silently returned.
Source
Thrown at s15_integrated_harness/code.py:256
path = _task_path(task.id)
temporary = path.with_name(
f".{path.name}.{os.getpid()}.{threading.get_ident()}.tmp"
)
try:
temporary.write_text(
json.dumps(asdict(task), indent=2), encoding="utf-8"
)
os.replace(temporary, path)
finally:
temporary.unlink(missing_ok=True)
def load_task(task_id: str) -> Task:
with task_lock:
data = json.loads(_task_path(task_id).read_text(encoding="utf-8"))
task = Task(**data)
if task.id != task_id:
raise ValueError(f"Task file ID does not match {task_id}")
if task.status not in {"pending", "in_progress", "completed"}:
raise ValueError(f"Invalid task status: {task.status}")
return task
def list_tasks() -> list[Task]:
with task_lock:
if not TASKS_DIR.exists():
return []
if not TASKS_ROOT.is_relative_to(WORKDIR.resolve()):
raise ValueError("Tasks directory escapes workspace")
return [load_task(path.stem)
for path in sorted(TASKS_DIR.glob("task_*.json"))]
def get_task_json(task_id: str) -> str:
return json.dumps(asdict(load_task(task_id)), indent=2)
View on GitHub (pinned to 985456f4ad)
Solutions
- Never rename or copy task files by hand — use create_task() and update via save_task().
- If a file was renamed, update its internal "id" field to match the new filename stem.
- Delete the corrupted file and recreate the task through the API.
Example fix
// before (shell) $ cp .tasks/task_0a1b2c3d.json .tasks/task_9f8e7d6c.json // after (python) new = create_task(orig.subject, orig.description, blockedBy=orig.blockedBy)
Defensive patterns
Strategy: validation
Validate before calling
import json
from pathlib import Path
def task_file_consistent(p: Path) -> bool:
try:
return json.loads(p.read_text())["id"] == p.stem
except Exception:
return False Try / catch
try:
task = load_task(task_id)
except ValueError as e:
if "ID does not match" in str(e):
# file renamed/hand-edited: reconcile id field with filename or recreate
raise Prevention
- Never rename/cp task files manually.
- Mutate tasks only through save_task()/APIs.
- Run a consistency sweep (id == filename stem) after any bulk migration.
When it happens
Trigger: Manually renaming a task_*.json file; copying a task file to a new name as a 'duplicate'; editing the JSON's id field by hand; a buggy external script rewriting task files.
Common situations: Developers cloning a task by cp task_a.json task_b.json; sed-based bulk edits of task files; manual 'fixes' to the tasks directory outside the API.
Related errors
- Invalid task status: {task.status}
- Invalid memory filename: {filename}
- Memory path escapes the store: {filename}
- consolidation returned empty or duplicate records
- Task store escapes the workspace
AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14).
Data as JSON: /api/errors/7acfd155f40f80a7.
Report an issue: GitHub.