abhigyanpatwari/GitNexus · error · ValueError

task id must be a simple artifact-safe slug: {task_id!r}

Error message

task id must be a simple artifact-safe slug: {task_id!r}

What it means

Raised by select_tasks when the task id fails the artifact-safe slug regex `[A-Za-z0-9][A-Za-z0-9._-]{0,127}` (runner_tasks.py:44). The id is used downstream as a filename and JSON key, so it must start alnum, be 1–128 chars, and contain only alnum/./_-. No slashes, spaces, colons, or leading dots/dashes.

Source

Thrown at eval/workflow_bench/runner_tasks.py:45

    selected: list[dict[str, Any]] = []
    skipped: list[str] = []
    seen: set[str] = set()
    required_strings = ("id", "class", "repo", "prompt", "verify")
    optional_strings = ("ref", "setup")
    for index, raw_task in enumerate(tasks):
        if not isinstance(raw_task, Mapping):
            raise ValueError(f"task {index} must be a mapping")
        task = dict(raw_task)
        for field in required_strings:
            if not isinstance(task.get(field), str) or not task[field].strip():
                raise ValueError(f"task {index} requires a nonblank string {field}")
        for field in optional_strings:
            if field in task and not isinstance(task[field], str):
                raise ValueError(f"task {task['id']} field {field} must be a string")
        task_id = task["id"]
        if not re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9._-]{0,127}", task_id):
            raise ValueError(f"task id must be a simple artifact-safe slug: {task_id!r}")
        if task_id in seen:
            raise ValueError(f"duplicate task id: {task_id}")
        seen.add(task_id)
        expensive = task.get("expensive", False)
        if not isinstance(expensive, bool):
            raise ValueError(f"task {task_id} expensive metadata must be boolean")
        copies = task.get("sandbox_copy", [])
        if not isinstance(copies, list) or not all(isinstance(path, str) and path for path in copies):
            raise ValueError(f"task {task_id} sandbox_copy must be a string list")
        dependencies = task.get("sandbox_dependencies", [])
        if not isinstance(dependencies, list):
            raise ValueError(f"task {task_id} sandbox_dependencies must be a list")
        for dependency in dependencies:
            if (
                not isinstance(dependency, Mapping)
                or set(dependency) != {"source", "target"}
                or not all(isinstance(dependency[field], str) and dependency[field] for field in ("source", "target"))
            ):

View on GitHub (pinned to d540b00184)

Solutions

  1. Rewrite the id to start with [A-Za-z0-9] and use only [A-Za-z0-9._-].
  2. Replace path separators and spaces with dashes.
  3. Shorten ids longer than 128 characters.

Example fix

# before
- id: "tasks/refactor: cli"
# after
- id: "refactor-cli"
Defensive patterns

Strategy: validation

Validate before calling

import re
SLUG = re.compile(r"[A-Za-z0-9][A-Za-z0-9._-]{0,127}")
for t in doc.get("tasks", []):
    if not SLUG.fullmatch(t.get("id", "")):
        raise SystemExit(f"bad task id slug: {t.get('id')!r}")

Type guard

def is_artifact_slug(value: str) -> bool:
    import re
    return bool(re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9._-]{0,127}", value))

Prevention

When it happens

Trigger: An id containing a path separator (`tasks/foo`), a leading dash (`-task`), a space, a colon, unicode, or exceeding 128 chars. Also fires for ids that start with a dot or underscore (`_foo`, `.bar`).

Common situations: Naming a task after a repo path; using a human-readable title with spaces as the id; a generated id that prefixes with a dash.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12). Data as JSON: /api/errors/3877642e0914ff03. Report an issue: GitHub.