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 raises ValueError when the result is empty. A task must have a non-empty human-readable subject; this is the earliest of create_task's three validation gates (subject, dependency existence, ID allocation).
Source
Thrown at s13_agent_teams/code.py:137
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 taskView on GitHub (pinned to 985456f4ad)
Solutions
- Check subject.strip() before calling create_task and supply a real title.
- If generating tasks in a loop, skip/log entries whose subject is blank instead of calling.
- Default missing subjects to a generated name like f'Task {date}' rather than ''.
Example fix
// before
task = create_task(subject or '') // ValueError
// after
if not (subject or '').strip():
raise ValueError('subject required')
task = create_task(subject) Defensive patterns
Strategy: validation
Validate before calling
def valid_subject(subject: str) -> bool:
return isinstance(subject, str) and bool(subject.strip()) Type guard
from typing import TypeGuard
def is_nonempty_subject(value: object) -> TypeGuard[str]:
return isinstance(value, str) and len(value.strip()) > 0 Prevention
- Validate subject.strip() in UI/forms before calling create_task.
- When templating subjects from optional data, assert the result is non-empty.
When it happens
Trigger: create_task(''), create_task(' ') (whitespace-only — it is stripped first), or passing a subject that is None-adjacent glue like f"{missing_var}" producing ''.
Common situations: Building subjects from optional template variables that are empty, forwarding unvalidated form input, or programmatic task generation where a list field was empty.
Related errors
- Invalid task ID: {task_id!r}
- Dependency not found: {dependency}
- Invalid task ID: {task_id!r}
- Task subject cannot be empty
- Max 20 todos allowed
AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14).
Data as JSON: /api/errors/ec322e9ff1eab0c7.
Report an issue: GitHub.