shareAI-lab/learn-claude-code · error · ValueError
Invalid status: {status}
Error message
Invalid status: {status} What it means
Raised by update() in agents/s12_worktree_task_isolation.py:175 when the status argument is truthy but outside {pending, in_progress, completed}. Same closed status set as s07 and also case-sensitive (no lowercasing), so "Completed" or "done" fail. On valid transitions the method also stamps updated_at.
Source
Thrown at agents/s12_worktree_task_isolation.py:175
"blockedBy": [],
"created_at": time.time(),
"updated_at": time.time(),
}
self._save(task)
self._next_id += 1
return json.dumps(task, indent=2)
def get(self, task_id: int) -> str:
return json.dumps(self._load(task_id), indent=2)
def exists(self, task_id: int) -> bool:
return self._path(task_id).exists()
def update(self, task_id: int, status: str = None, owner: str = None) -> str:
task = self._load(task_id)
if status:
if status not in ("pending", "in_progress", "completed"):
raise ValueError(f"Invalid status: {status}")
task["status"] = status
if owner is not None:
task["owner"] = owner
task["updated_at"] = time.time()
self._save(task)
return json.dumps(task, indent=2)
def bind_worktree(self, task_id: int, worktree: str, owner: str = "") -> str:
task = self._load(task_id)
task["worktree"] = worktree
if owner:
task["owner"] = owner
if task["status"] == "pending":
task["status"] = "in_progress"
task["updated_at"] = time.time()
self._save(task)
return json.dumps(task, indent=2)
View on GitHub (pinned to 985456f4ad)
Solutions
- Use exactly "pending", "in_progress", "completed"
- Normalize at the call site: status.strip().lower() and map "done"->"completed"
- Do not rely on status="" to mean pending — it means 'leave unchanged'
Example fix
# before tasks.update(task_id=4, status="In_Progress") # ValueError: Invalid status: In_Progress # after status = "in_progress" tasks.update(task_id=4, status=status)
Defensive patterns
Strategy: validation
Validate before calling
VALID = {"pending", "in_progress", "completed"}
status = status.strip().lower() if isinstance(status, str) else None
status = {"done": "completed"}.get(status, status)
assert status is None or status in VALID, f"Invalid status: {status}; allowed {sorted(VALID)}" Type guard
WORKTREE_STATUSES = frozenset(("pending", "in_progress", "completed"))
def is_valid_worktree_status(s: object) -> bool:
return s is None or (isinstance(s, str) and s in WORKTREE_STATUSES) # case-sensitive; '' means unchanged Try / catch
try:
TASKS.update(task_id, status)
except ValueError as e:
if "Invalid status" in str(e):
return f"Tool error: {e}. Allowed: pending, in_progress, completed (exact, lowercase)."
raise Prevention
- Lowercase and strip status before the call; map 'done' to 'completed'
- Remember empty/None status means 'leave unchanged', not 'pending'
- No cancelled/blocked status exists — use owner/worktree fields for extra state
When it happens
Trigger: task_update with status "done", "cancelled", "blocked", "In_Progress", or any free-text value. Passing status="" is falsy and silently skips the check (no error, no change) — a quieter trap worth knowing.
Common situations: Models abbreviating to "done". Passing user-facing strings unnormalized. Expecting cancelled/blocked states that the worktree task schema does not have.
Related errors
- Invalid status: {status}
- Task {task_id} not found
- Item {item_id}: invalid status '{status}'
- Only one task can be in_progress at a time
- Task {task_id} not found
AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14).
Data as JSON: /api/errors/08e476526b52301b.
Report an issue: GitHub.