{"record":{"id":"3f976e3ea65649a2","repo":"can1357/oh-my-pi","slug":"todo-items-must-provide-a-non-empty-content-valu","errorCode":null,"errorMessage":"Todo items must provide a non-empty 'content' value","messagePattern":"Todo items must provide a non-empty 'content' value","errorType":"exception","errorClass":"RpcError","httpStatus":null,"severity":"error","filePath":"python/omp-rpc/src/omp_rpc/client.py","lineNumber":1718,"sourceCode":"                    \"content\": seed,\n                    \"status\": cast(JsonValue, \"pending\"),\n                }\n\n            if isinstance(seed, TodoItem):\n                if seed.status not in _TODO_STATUS_VALUES:\n                    raise RpcError(f\"Unsupported todo status: {seed.status}\")\n                return {\n                    \"id\": seed.id or next_task(),\n                    \"content\": seed.content,\n                    \"status\": cast(JsonValue, seed.status),\n                    \"notes\": seed.notes,\n                    \"details\": seed.details,\n                    \"blocker\": seed.blocker,\n                }\n\n            content = seed.get(\"content\")\n            if not isinstance(content, str) or not content.strip():\n                raise RpcError(\"Todo items must provide a non-empty 'content' value\")\n\n            raw_id = seed.get(\"id\")\n            raw_status = seed.get(\"status\")\n            raw_notes = seed.get(\"notes\")\n            raw_details = seed.get(\"details\")\n            raw_blocker = seed.get(\"blocker\")\n            if isinstance(raw_status, str):\n                if raw_status not in _TODO_STATUS_VALUES:\n                    raise RpcError(f\"Unsupported todo status: {raw_status}\")\n                status: TodoStatus = cast(TodoStatus, raw_status)\n            else:\n                status = \"pending\"\n            return {\n                \"id\": str(raw_id)\n                if isinstance(raw_id, str) and raw_id\n                else next_task(),\n                \"content\": content,\n                \"status\": cast(JsonValue, status),","sourceCodeStart":1700,"sourceCodeEnd":1736,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/python/omp-rpc/src/omp_rpc/client.py#L1700-L1736","documentation":"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.","triggerScenarios":"Passing a dict todo like {\"id\": \"1\"} without 'content', content=None, content=123, or content=\"   \" into the todo seeding API.","commonSituations":"Building todo dicts from external data (CSV, API) with empty rows; key-name mismatches ('text' vs 'content'); stripping content and dropping it when blank.","solutions":["Ensure every seed dict has a non-empty string 'content' before calling the API","Map your source key (e.g. 'text' or 'title') to 'content'","Filter out blank rows in your data-loading step","Validate/normalize with a small preprocessing function that raises or skips invalid items"],"exampleFix":"// before\nseed = {\"id\": \"1\", \"content\": row.get(\"text\")}  # may be None\n// after\ncontent = (row.get(\"text\") or \"\").strip()\nif not content:\n    continue\nseed = {\"id\": \"1\", \"content\": content}","handlingStrategy":"validation","validationCode":"def valid_todo_seed(seed: dict) -> bool:\n    c = seed.get(\"content\")\n    return isinstance(c, str) and bool(c.strip())\nseeds = [s for s in raw_seeds if valid_todo_seed(s)]","typeGuard":"def has_content(seed: object) -> TypeGuard[dict]:\n    return (isinstance(seed, dict)\n            and isinstance(seed.get(\"content\"), str)\n            and seed[\"content\"].strip() != \"\")","tryCatchPattern":"try:\n    client.seed_todos(seeds)\nexcept RpcError as exc:\n    if \"non-empty 'content'\" in str(exc):\n        log.warning(\"dropping blank todo seeds\")\n        client.seed_todos([s for s in seeds if valid_todo_seed(s)])\n    else:\n        raise","preventionTips":["Validate/filter todo seeds at data-load time, before the RPC call","Strip and skip blank content rows from external sources","Prefer constructing TodoItem objects (validated) over raw dicts"],"tags":["rpc","validation","todos","missing-field"],"backgroundTag":"missing-required-field","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}