shareAI-lab/learn-claude-code · error · ValueError

Task subject cannot be empty

Error message

Task subject cannot be empty

What it means

create_task() strips the subject and refuses to create a task with an empty subject. The subject is the task's primary identifier shown in listings and to teammate agents, so blank subjects are rejected outright rather than defaulted.

Source

Thrown at s15_integrated_harness/code.py:212

    blockedBy: list[str]
    worktree: str | None = None


def _task_path(task_id: str) -> Path:
    if not isinstance(task_id, str) or not TASK_ID_PATTERN.fullmatch(task_id):
        raise ValueError(f"Invalid task ID: {task_id!r}")
    path = (TASKS_DIR / f"{task_id}.json").resolve()
    if (not TASKS_ROOT.is_relative_to(WORKDIR.resolve())
            or not path.is_relative_to(TASKS_ROOT)):
        raise ValueError(f"Invalid task ID: {task_id!r}")
    return path


def create_task(subject: str, description: str = "",
                blockedBy: list[str] | None = None) -> Task:
    subject = subject.strip()
    if not subject:
        raise ValueError("Task subject cannot be empty")
    dependencies = list(dict.fromkeys(blockedBy or []))
    with task_store_lock():
        for dependency in dependencies:
            if not _task_path(dependency).is_file():
                raise ValueError(f"Dependency not found: {dependency}")
        for _ in range(100):
            task = Task(
                id=f"task_{secrets.token_hex(4)}",
                subject=subject,
                description=description,
                status="pending",
                owner=None,
                blockedBy=dependencies,
            )
            try:
                with _task_path(task.id).open("x", encoding="utf-8") as handle:
                    json.dump(asdict(task), handle, indent=2)
                return task

View on GitHub (pinned to 985456f4ad)

Solutions

  1. Pass a non-empty, meaningful subject string (it is .strip()ed, so trim whitespace first if you need exact content).
  2. If automating, fall back to a derived subject (e.g. first line of description) instead of an empty string.
  3. Validate subject.strip() on the caller side before invoking the tool.

Example fix

// before
create_task(subject="", description="fix login bug")

// after
create_task(subject="Fix login bug", description="fix login bug")
Defensive patterns

Strategy: validation

Validate before calling

subject = subject.strip() if isinstance(subject, str) else ""
if not subject:
    subject = description.strip().splitlines()[0] if description.strip() else None
if subject:
    task = create_task(subject, description)

Type guard

def is_valid_subject(subject) -> bool:
    return isinstance(subject, str) and bool(subject.strip())

Try / catch

try:
    create_task(subject, description)
except ValueError as e:
    if "subject cannot be empty" in str(e):
        # prompt the caller/model for a subject; do not default silently
        raise

Prevention

When it happens

Trigger: Calling create_task(subject="" ), create_task(" "), or passing a subject that is only whitespace. Common when the argument comes from an LLM tool call where the model put the subject in the wrong parameter or omitted it.

Common situations: Model fills description but leaves subject blank; a script maps the wrong column/field into subject; whitespace-padded input from a form or CSV.

Related errors


AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14). Data as JSON: /api/errors/c2ea5e6ab847d92e. Report an issue: GitHub.