usestrix/strix · error · TypeError
Each todo entry must be a string or object with a title
Error message
Each todo entry must be a string or object with a title
What it means
Thrown by the todo normalizer when an element inside the todos list is neither a string nor a dict. Strings are treated as bare titles; dicts carry title/description/priority. Any other element type (number, null, nested list) is rejected with this TypeError.
Source
Thrown at strix/tools/todo/tools.py:217
data = json.loads(stripped)
except json.JSONDecodeError:
entries = [line.strip(" -*\t") for line in stripped.splitlines() if line.strip(" -*\t")]
return [{"title": entry} for entry in entries]
if isinstance(data, dict):
data = [data]
if not isinstance(data, list):
raise TypeError("Todos must be provided as a list, dict, or JSON string")
normalized: list[dict[str, Any]] = []
for item in data:
if isinstance(item, str):
title = item.strip()
if title:
normalized.append({"title": title})
continue
if not isinstance(item, dict):
raise TypeError("Each todo entry must be a string or object with a title")
title = item.get("title", "")
if not isinstance(title, str) or not title.strip():
raise ValueError("Each todo entry must include a non-empty 'title'")
normalized.append(
{
"title": title.strip(),
"description": (item.get("description") or "").strip() or None,
"priority": item.get("priority"),
},
)
return normalized
def _apply_single_update(
agent_todos: dict[str, dict[str, Any]],
todo_id: str,
title: str | None = None,
description: str | None = None,View on GitHub (pinned to 8551339130)
Solutions
- Make every list element either a plain title string or an object with a 'title' key
- Drop null/undefined entries before calling the tool
- Convert numeric entries to strings if they were meant as titles
Example fix
# before todos = [null, "write tests"] # after todos = ["write tests"]
Defensive patterns
Strategy: type-guard
Validate before calling
entries = [e for e in todos if e is not None]
if not all(isinstance(e, (str, dict)) for e in entries):
raise TypeError("todo entries must be str or dict") Type guard
def is_todo_entry(v) -> bool:
return isinstance(v, (str, dict)) Try / catch
try:
tool.write_todos(entries)
except TypeError as e:
if "string or object" in str(e):
entries = [e for e in entries if isinstance(e, (str, dict))]
tool.write_todos(entries) Prevention
- Filter null and non-str/dict elements out of agent-generated arrays
- Validate with a small schema (e.g. pydantic) at the boundary before calling the tool
When it happens
Trigger: todos=[42, {'title': 'x'}], todos=[["a"]], or a JSON payload like '[null, "task"]' where an element parses to null.
Common situations: LLM emitting mixed-type arrays (numbers as task ids), JSON null elements from sparse arrays, or wrapping titles in an extra array layer.
Related errors
- Todos must be provided as a list, dict, or JSON string
- Updates must be valid JSON
- Updates must be a list of update objects
- Each update must be an object with todo_id
- Each update must include 'todo_id'
AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15).
Data as JSON: /api/errors/965c1bf25b1c7913.
Report an issue: GitHub.