can1357/oh-my-pi · error · ValueError

todo_phases.toml[{task_kind!r}][{phase_index}].tasks must be

Error message

todo_phases.toml[{task_kind!r}][{phase_index}].tasks must be a non-empty list

What it means

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.

Source

Thrown at python/robomp/src/persona.py:86

        raise ValueError(f"{context} must be a non-empty string")
    return value


def seed_phases(task_kind: str) -> list[dict[str, Any]]:
    raw_phases = _load_toml("todo_phases.toml").get(task_kind, [])
    if not isinstance(raw_phases, list):
        raise ValueError(f"todo_phases.toml[{task_kind!r}] must be a list of phases")

    phases: list[dict[str, Any]] = []
    for phase_index, raw_phase in enumerate(raw_phases):
        phase = _require_mapping(raw_phase, f"todo_phases.toml[{task_kind!r}][{phase_index}]")
        name = _require_nonempty_str(
            phase.get("name"),
            f"todo_phases.toml[{task_kind!r}][{phase_index}].name",
        )
        raw_tasks = phase.get("tasks")
        if not isinstance(raw_tasks, list) or not raw_tasks:
            raise ValueError(f"todo_phases.toml[{task_kind!r}][{phase_index}].tasks must be a non-empty list")
        tasks = [
            _require_nonempty_str(
                task,
                f"todo_phases.toml[{task_kind!r}][{phase_index}].tasks[{task_index}]",
            )
            for task_index, task in enumerate(raw_tasks)
        ]
        phases.append({"name": name, "tasks": tasks})
    return phases


def _host_tool_entry(tool_name: str) -> Mapping[str, Any]:
    return _require_mapping(
        _load_toml("host_tools.toml").get(tool_name),
        f"host_tools.toml[{tool_name!r}]",
    )

View on GitHub (pinned to 9690622007)

Solutions

  1. Open todo_phases.toml and add at least one non-empty string to the 'tasks' array of the phase named in the error path
  2. Ensure 'tasks' is a TOML array (tasks = ["..."]), not a bare string or table
  3. If the phase should be empty, remove the phase entry entirely rather than leaving tasks = []
  4. Validate the file parses with a TOML linter before re-running seed_phases

Example fix

# before
todo_phases.toml:
[[task_kind.phases]]
name = "review"
tasks = []

# after
todo_phases.toml:
[[task_kind.phases]]
name = "review"
tasks = ["check formatting", "run tests"]
Defensive patterns

Strategy: validation

Validate before calling

import tomllib
with open("todo_phases.toml", "rb") as f:
    cfg = tomllib.load(f)
for kind, phases in cfg.items():
    for i, phase in enumerate(phases):
        tasks = phase.get("tasks")
        if not isinstance(tasks, list) or not tasks:
            raise ValueError(f"phase {kind}[{i}].name={phase.get('name')!r} needs a non-empty tasks list")

Type guard

def has_tasks(phase: dict) -> bool:
    tasks = phase.get("tasks")
    return isinstance(tasks, list) and len(tasks) > 0 and all(isinstance(t, str) and t for t in tasks)

Try / catch

try:
    seed_phases("todo_phases.toml")
except ValueError as e:
    logger.error("todo_phases.toml invalid: %s", e)
    raise SystemExit(2) from e

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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