shareAI-lab/learn-claude-code · error · ValueError

Item {i}: content required

Error message

Item {i}: content required

What it means

Raised by TodoManager.update in s_full.py when a todo item's 'content' field is missing, None, or whitespace after str().strip(). The manager validates each item and reports the failing index i (0-based) so callers can locate the bad entry. No state is mutated — the whole update is rejected before self.items is replaced.

Source

Thrown at agents/s_full.py:133

            return f"Error: Text not found in {path}"
        fp.write_text(c.replace(old_text, new_text, 1))
        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")

View on GitHub (pinned to 985456f4ad)

Solutions

  1. Ensure every item includes a non-empty content string: {"content": "Implement login", ...}
  2. Strip and validate items client-side before calling update, dropping or fixing empty ones
  3. Use the reported index i to find the offending item quickly in large lists
  4. Default missing content to a placeholder like "(untitled step)" if your flow allows it

Example fix

// before
TODOS.update([{"content": "  ", "status": "pending", "activeForm": "Working"}])
// after
TODOS.update([{"content": "Implement login", "status": "pending", "activeForm": "Working"}])
Defensive patterns

Strategy: validation

Validate before calling

def clean_todos(items):
    out = []
    for i, it in enumerate(items):
        if not str(it.get('content', '')).strip():
            it = {**it, 'content': f'(step {i})'}  # or skip
        out.append(it)
    return out

TODOS.update(clean_todos(items))

Type guard

def is_valid_todo_item(item: object) -> bool:
    return (
        isinstance(item, dict)
        and bool(str(item.get('content', '')).strip())
    )

Try / catch

try:
    TODOS.update(items)
except ValueError as e:
    m = re.match(r"Item (\d+): content required", str(e))
    if m:
        i = int(m.group(1))
        items[i]['content'] = f'(step {i})'
        TODOS.update(items)
    else:
        raise

Prevention

When it happens

Trigger: Calling the todo tool with [{"status": "pending", "activeForm": "x"}] (no content key), content: "" or content: " ", or content: None coerced to the string "None" only when a key exists with an empty value. Index i in the message maps to position in the submitted list.

Common situations: LLM agents emitting items with only status and activeForm; content set to an empty string when a plan step has no title yet; whitespace-only content pasted from a checklist.

Related errors


AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14). Data as JSON: /api/errors/404d4c7249cdc1c4. Report an issue: GitHub.