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 .tasks/<task_id>.json, constructs Task(**data), and requires the 'id' field inside the JSON to equal the task_id used to locate the file. A mismatch means the file content and filename disagree — manual edits, a botched rename/copy, or two writers racing.
Source
Thrown at s13_agent_teams/code.py:181
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(task_id: str) -> str:
"""Return full task details as JSON."""
task = load_task(task_id)View on GitHub (pinned to 985456f4ad)
Solutions
- Don't clone tasks by copying files; write a small script that loads, changes id, and saves via save_task().
- Fix a mismatched file by editing its id field to match the filename (or renaming the file to the embedded id).
- Keep all writes going through save_task(), which writes atomically via a temp file and os.replace.
Example fix
# before (broken: copied file)
# .tasks/task_aaaaaaaa.json contains "id": "task_bbbbbbbb"
# after
import json, pathlib
p = pathlib.Path('.tasks/task_aaaaaaaa.json')
data = json.loads(p.read_text())
data['id'] = 'task_aaaaaaaa'
p.write_text(json.dumps(data, indent=2)) Defensive patterns
Strategy: validation
Validate before calling
import json
from pathlib import Path
def task_file_consistent(path: Path) -> bool:
try:
return json.loads(path.read_text())['id'] == path.stem
except (OSError, ValueError, KeyError):
return False Try / catch
try:
task = load_task(task_id)
except ValueError as exc:
if 'does not match' in str(exc):
# repair: rewrite file's id to match filename, or drop the corrupt file
log_corrupt(task_id)
(TASKS_DIR / f'{task_id}.json').unlink(missing_ok=True)
return None
raise Prevention
- Never duplicate task files with cp; use load/modify/save via save_task.
- Audit .tasks for filename/id mismatches after any manual intervention.
- Write only through save_task() so id and filename stay in lockstep.
When it happens
Trigger: Renaming a task file without editing its id field; copying task_a.json over task_b.json; hand-editing .tasks/*.json; a partial/interleaved write leaving stale content under a new filename.
Common situations: Users duplicating task files to clone tasks; external scripts writing the directory without using save_task(); editor auto-save during a save_task() atomic replace.
Related errors
- Invalid task status: {task.status}
- consolidation returned empty or duplicate records
- Task file ID does not match {task_id}
- Invalid task status: {task.status}
- Invalid task ID: {task_id!r}
AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14).
Data as JSON: /api/errors/fddc06bf2af4b50f.
Report an issue: GitHub.