shareAI-lab/learn-claude-code · warning · ValueError
Max 20 todos allowed
Error message
Max 20 todos allowed
What it means
Raised by TodoManager.update in s05_todo_write/code.py when the incoming todos list has more than 20 entries. The cap is checked after parsing/type validation but before per-item validation, so a 25-item list fails immediately. State is untouched: self.items keeps the previous value.
Source
Thrown at s05_todo_write/code.py:127
class TodoManager:
def __init__(self):
self.items: list[dict] = []
def update(self, todos: list | str) -> str:
if isinstance(todos, str):
try:
todos = json.loads(todos)
except json.JSONDecodeError:
try:
todos = ast.literal_eval(todos)
except (SyntaxError, ValueError) as e:
raise ValueError("todos must be a list or JSON array string") from e
if not isinstance(todos, list):
raise ValueError("todos must be a list")
if len(todos) > 20:
raise ValueError("Max 20 todos allowed")
validated = []
in_progress_count = 0
for index, todo in enumerate(todos):
if not isinstance(todo, dict):
raise ValueError(f"todos[{index}] must be an object")
content = str(todo.get("content", "")).strip()
status = str(todo.get("status", "pending")).lower()
if not content:
raise ValueError(f"todos[{index}] requires content")
if status not in ("pending", "in_progress", "completed"):
raise ValueError(f"todos[{index}] has invalid status '{status}'")
if status == "in_progress":
in_progress_count += 1
validated.append({"content": content, "status": status})
if in_progress_count > 1:View on GitHub (pinned to 985456f4ad)
Solutions
- Merge related steps to bring the count to 20 or fewer
- Replace the list each phase instead of growing it monotonically
- Enforce len(todos) <= 20 in the calling code or tool schema (maxItems: 20)
Example fix
// before TODOS.update(all_steps) # 24 items // after TODOS.update(all_steps[:20]) # or merge related steps first
Defensive patterns
Strategy: validation
Validate before calling
MAX = 20
if len(todos) > MAX:
todos = todos[:MAX] # or merge/drop consciously
assert len(todos) <= MAX
TODOS.update(todos) Prevention
- Declare maxItems: 20 in the tool schema
- Replace, don't accumulate, todo lists across phases
- Keep plans coarse-grained by design
When it happens
Trigger: update() called with 21 or more todo dicts (or a JSON string deserializing to such a list).
Common situations: Fine-grained agent plans (one todo per file edited); importing long external checklists; appending instead of replacing when the list is already near the cap.
Related errors
- Max 20 todos
- Item {i}: content required
- Item {i}: invalid status '{status}'
- todos must be a list or JSON array string
- todos[{index}] requires content
AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14).
Data as JSON: /api/errors/a6efd994643ad89c.
Report an issue: GitHub.