{"record":{"id":"a2b66fc5554db35d","repo":"can1357/oh-my-pi","slug":"todo-phases-toml-task-kind-r-phase-index-tas","errorCode":null,"errorMessage":"todo_phases.toml[{task_kind!r}][{phase_index}].tasks must be a non-empty list","messagePattern":"todo_phases\\.toml\\[(.+?)\\]\\[(.+?)\\]\\.tasks must be a non-empty list","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/robomp/src/persona.py","lineNumber":86,"sourceCode":"        raise ValueError(f\"{context} must be a non-empty string\")\n    return value\n\n\ndef seed_phases(task_kind: str) -> list[dict[str, Any]]:\n    raw_phases = _load_toml(\"todo_phases.toml\").get(task_kind, [])\n    if not isinstance(raw_phases, list):\n        raise ValueError(f\"todo_phases.toml[{task_kind!r}] must be a list of phases\")\n\n    phases: list[dict[str, Any]] = []\n    for phase_index, raw_phase in enumerate(raw_phases):\n        phase = _require_mapping(raw_phase, f\"todo_phases.toml[{task_kind!r}][{phase_index}]\")\n        name = _require_nonempty_str(\n            phase.get(\"name\"),\n            f\"todo_phases.toml[{task_kind!r}][{phase_index}].name\",\n        )\n        raw_tasks = phase.get(\"tasks\")\n        if not isinstance(raw_tasks, list) or not raw_tasks:\n            raise ValueError(f\"todo_phases.toml[{task_kind!r}][{phase_index}].tasks must be a non-empty list\")\n        tasks = [\n            _require_nonempty_str(\n                task,\n                f\"todo_phases.toml[{task_kind!r}][{phase_index}].tasks[{task_index}]\",\n            )\n            for task_index, task in enumerate(raw_tasks)\n        ]\n        phases.append({\"name\": name, \"tasks\": tasks})\n    return phases\n\n\ndef _host_tool_entry(tool_name: str) -> Mapping[str, Any]:\n    return _require_mapping(\n        _load_toml(\"host_tools.toml\").get(tool_name),\n        f\"host_tools.toml[{tool_name!r}]\",\n    )\n\n","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/python/robomp/src/persona.py#L68-L104","documentation":"This ValueError is raised while loading todo_phases.toml during phase seeding: a phase entry's 'tasks' key is either missing, not a list, or an empty list. The library requires every phase to declare at least one task string so seeded todo data is never silently empty.","triggerScenarios":"Calling seed_phases with a todo_phases.toml where a [[...phases]] entry omits 'tasks', sets tasks = [] (empty array), or sets tasks to a non-list value like a string or inline table.","commonSituations":"Hand-editing the TOML config and accidentally deleting the tasks entries; commenting out all task lines leaving an empty array; copying a phase template and forgetting to fill tasks in.","solutions":["Open todo_phases.toml and add at least one non-empty string to the 'tasks' array of the phase named in the error path","Ensure 'tasks' is a TOML array (tasks = [\"...\"]), not a bare string or table","If the phase should be empty, remove the phase entry entirely rather than leaving tasks = []","Validate the file parses with a TOML linter before re-running seed_phases"],"exampleFix":"# before\ntodo_phases.toml:\n[[task_kind.phases]]\nname = \"review\"\ntasks = []\n\n# after\ntodo_phases.toml:\n[[task_kind.phases]]\nname = \"review\"\ntasks = [\"check formatting\", \"run tests\"]","handlingStrategy":"validation","validationCode":"import tomllib\nwith open(\"todo_phases.toml\", \"rb\") as f:\n    cfg = tomllib.load(f)\nfor kind, phases in cfg.items():\n    for i, phase in enumerate(phases):\n        tasks = phase.get(\"tasks\")\n        if not isinstance(tasks, list) or not tasks:\n            raise ValueError(f\"phase {kind}[{i}].name={phase.get('name')!r} needs a non-empty tasks list\")","typeGuard":"def has_tasks(phase: dict) -> bool:\n    tasks = phase.get(\"tasks\")\n    return isinstance(tasks, list) and len(tasks) > 0 and all(isinstance(t, str) and t for t in tasks)","tryCatchPattern":"try:\n    seed_phases(\"todo_phases.toml\")\nexcept ValueError as e:\n    logger.error(\"todo_phases.toml invalid: %s\", e)\n    raise SystemExit(2) from e","preventionTips":["Keep a checked-in schema/example todo_phases.toml and copy new phases from it","Run a TOML lint/validate step in CI before seeding","Never leave tasks = [] placeholders in committed config","Review TOML diffs for accidentally deleted array entries"],"tags":["config","toml","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}