shareAI-lab/learn-claude-code · error · ValueError
Item {i}: invalid status '{status}'
Error message
Item {i}: invalid status '{status}' What it means
Raised by TodoManager.update in s_full.py when an item's status (lowercased string of item.get('status', 'pending')) is not one of pending/in_progress/completed. The value is coerced with str() before comparison, so non-string statuses like booleans or ints also fail after coercion ('true', '1'). The failing index i and the bad value are both included in the message.
Source
Thrown at agents/s_full.py:135
return f"Edited {path}"
except Exception as e:
return f"Error: {e}"
# === SECTION: todos (s03) ===
class TodoManager:
def __init__(self):
self.items = []
def update(self, items: list) -> str:
validated, ip = [], 0
for i, item in enumerate(items):
content = str(item.get("content", "")).strip()
status = str(item.get("status", "pending")).lower()
af = str(item.get("activeForm", "")).strip()
if not content: raise ValueError(f"Item {i}: content required")
if status not in ("pending", "in_progress", "completed"):
raise ValueError(f"Item {i}: invalid status '{status}'")
if not af: raise ValueError(f"Item {i}: activeForm required")
if status == "in_progress": ip += 1
validated.append({"content": content, "status": status, "activeForm": af})
if len(validated) > 20: raise ValueError("Max 20 todos")
if ip > 1: raise ValueError("Only one in_progress allowed")
self.items = validated
return self.render()
def render(self) -> str:
if not self.items: return "No todos."
lines = []
for item in self.items:
m = {"completed": "[x]", "in_progress": "[>]", "pending": "[ ]"}.get(item["status"], "[?]")
suffix = f" <- {item['activeForm']}" if item["status"] == "in_progress" else ""
lines.append(f"{m} {item['content']}{suffix}")
done = sum(1 for t in self.items if t["status"] == "completed")
lines.append(f"\n({done}/{len(self.items)} completed)")
return "\n".join(lines)View on GitHub (pinned to 985456f4ad)
Solutions
- Map your statuses to the allowed set before update: {'done': 'completed', 'doing': 'in_progress', 'todo': 'pending'}
- Validate with status in ('pending', 'in_progress', 'completed') client-side and reject early
- Note that casing is tolerated (values are lowercased) but word separators are not — use snake_case
Example fix
// before
TODOS.update([{"content": "x", "status": "done", "activeForm": ""}])
// after
TODOS.update([{"content": "x", "status": "completed", "activeForm": ""}]) Defensive patterns
Strategy: validation
Validate before calling
ALLOWED = ('pending', 'in_progress', 'completed')
MAP = {'done': 'completed', 'todo': 'pending', 'doing': 'in_progress', 'inprogress': 'in_progress'}
items = [{**it, 'status': MAP.get(str(it.get('status', 'pending')).lower(), str(it.get('status', 'pending')).lower())} for it in items]
assert all(it['status'] in ALLOWED for it in items)
TODOS.update(items) Type guard
def is_valid_status(s: object) -> bool:
return str(s if s is not None else 'pending').lower() in ('pending', 'in_progress', 'completed') Try / catch
try:
TODOS.update(items)
except ValueError as e:
m = re.search(r"invalid status '(.*?)'", str(e))
if m:
fixed = MAP.get(m.group(1))
if fixed:
items = [{**it, 'status': fixed} if str(it['status']).lower() == m.group(1) else it for it in items]
TODOS.update(items)
else:
raise
else:
raise Prevention
- Use an enum in the tool schema with only the three allowed values
- Map external/natural-language statuses before calling update
- Remember casing is normalized but separators are not
When it happens
Trigger: Passing status "done", "in-progress" (hyphen), "In Progress" (this one actually works because of .lower(), but "in progress" with a space fails), status True (coerces to "true"), or status 2. Each produces the message with the coerced string shown.
Common situations: LLMs writing natural-language statuses like "done" or "in review"; camelCase "inProgress" (lowercases to "inprogress", still invalid); enum values copied from a different todo system's schema.
Related errors
- Item {i}: content required
- todos must be a list or JSON array string
- todos[{index}] requires content
- todos[{index}] has invalid status '{status}'
- Max 20 todos allowed
AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14).
Data as JSON: /api/errors/b1b165295f688f9e.
Report an issue: GitHub.