can1357/oh-my-pi · error · RpcError

Todo items must provide a non-empty 'content' value

Error message

Todo items must provide a non-empty 'content' value

What it means

RpcError raised when seeding a todo from a raw mapping whose 'content' is missing, not a string, or whitespace-only. Todo items must carry non-empty text content before being sent to the server.

Source

Thrown at python/omp-rpc/src/omp_rpc/client.py:1718

                    "content": seed,
                    "status": cast(JsonValue, "pending"),
                }

            if isinstance(seed, TodoItem):
                if seed.status not in _TODO_STATUS_VALUES:
                    raise RpcError(f"Unsupported todo status: {seed.status}")
                return {
                    "id": seed.id or next_task(),
                    "content": seed.content,
                    "status": cast(JsonValue, seed.status),
                    "notes": seed.notes,
                    "details": seed.details,
                    "blocker": seed.blocker,
                }

            content = seed.get("content")
            if not isinstance(content, str) or not content.strip():
                raise RpcError("Todo items must provide a non-empty 'content' value")

            raw_id = seed.get("id")
            raw_status = seed.get("status")
            raw_notes = seed.get("notes")
            raw_details = seed.get("details")
            raw_blocker = seed.get("blocker")
            if isinstance(raw_status, str):
                if raw_status not in _TODO_STATUS_VALUES:
                    raise RpcError(f"Unsupported todo status: {raw_status}")
                status: TodoStatus = cast(TodoStatus, raw_status)
            else:
                status = "pending"
            return {
                "id": str(raw_id)
                if isinstance(raw_id, str) and raw_id
                else next_task(),
                "content": content,
                "status": cast(JsonValue, status),

View on GitHub (pinned to 9690622007)

Solutions

  1. Ensure every seed dict has a non-empty string 'content' before calling the API
  2. Map your source key (e.g. 'text' or 'title') to 'content'
  3. Filter out blank rows in your data-loading step
  4. Validate/normalize with a small preprocessing function that raises or skips invalid items

Example fix

// before
seed = {"id": "1", "content": row.get("text")}  # may be None
// after
content = (row.get("text") or "").strip()
if not content:
    continue
seed = {"id": "1", "content": content}
Defensive patterns

Strategy: validation

Validate before calling

def valid_todo_seed(seed: dict) -> bool:
    c = seed.get("content")
    return isinstance(c, str) and bool(c.strip())
seeds = [s for s in raw_seeds if valid_todo_seed(s)]

Type guard

def has_content(seed: object) -> TypeGuard[dict]:
    return (isinstance(seed, dict)
            and isinstance(seed.get("content"), str)
            and seed["content"].strip() != "")

Try / catch

try:
    client.seed_todos(seeds)
except RpcError as exc:
    if "non-empty 'content'" in str(exc):
        log.warning("dropping blank todo seeds")
        client.seed_todos([s for s in seeds if valid_todo_seed(s)])
    else:
        raise

Prevention

When it happens

Trigger: Passing a dict todo like {"id": "1"} without 'content', content=None, content=123, or content=" " into the todo seeding API.

Common situations: Building todo dicts from external data (CSV, API) with empty rows; key-name mismatches ('text' vs 'content'); stripping content and dropping it when blank.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/3f976e3ea65649a2. Report an issue: GitHub.