Hmbown/CodeWhale · error

fleet task {} instructions cannot be empty

Error message

fleet task {} instructions cannot be empty

What it means

validate_task_spec_document rejects a task whose instructions string is empty or only whitespace. Instructions are what the worker executes, so a blank value is treated as an authoring error, not a no-op.

Source

Thrown at crates/tui/src/fleet/task_spec.rs:126

    };
    let doc = parsed.into_document(fallback_name);
    validate_task_spec_document(&doc)?;
    Ok(doc)
}

pub fn validate_task_spec_document(doc: &FleetTaskSpecDocument) -> Result<()> {
    if doc.tasks.is_empty() {
        bail!("fleet task spec must include at least one task");
    }
    let mut ids = BTreeSet::new();
    for task in &doc.tasks {
        validate_fleet_identity("task id", &task.id)?;
        if !ids.insert(task.id.clone()) {
            bail!("duplicate fleet task id {}", task.id);
        }
        validate_fleet_name(&format!("task {} name", task.id), &task.name)?;
        if task.instructions.trim().is_empty() {
            bail!("fleet task {} instructions cannot be empty", task.id);
        }
        if let Some(objective) = &task.objective
            && objective.trim().is_empty()
        {
            bail!("fleet task {} objective cannot be empty", task.id);
        }
        validate_worker_profile(&task.id, task.worker.as_ref())?;
        validate_tags(&task.id, &task.tags)?;
        validate_workspace_requirements(task)?;
    }
    let mut worker_ids = BTreeSet::new();
    for worker in &doc.workers {
        validate_fleet_identity("worker id", &worker.id)?;
        if !worker_ids.insert(worker.id.clone()) {
            bail!("duplicate fleet worker id {}", worker.id);
        }
        validate_fleet_name(&format!("worker {} name", worker.id), &worker.name)?;
    }

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Write real instructions text for the task id named in the error
  2. If templating, fail the build when a substitution produces an empty instructions value
  3. Delete the task entirely if it is a leftover placeholder

Example fix

// before
{ "id": "lint", "name": "lint", "instructions": "" }

// after
{ "id": "lint", "name": "lint", "instructions": "Run cargo clippy --workspace and report warnings" }
Defensive patterns

Strategy: validation

Validate before calling

fn instructions_present(tasks: &[FleetTaskSpec]) -> bool {
    tasks.iter().all(|t| !t.instructions.trim().is_empty())
}

Type guard

function hasInstructions(t: { instructions: string }): boolean {
  return t.instructions.trim().length > 0;
}

Try / catch

if let Err(err) = load_task_spec_document(&path) {
    if err.to_string().contains("instructions cannot be empty") {
        eprintln!("a task in {path:?} has blank instructions - fill or remove it");
    }
    return Err(err);
}

Prevention

When it happens

Trigger: A task with "instructions": "" or "instructions": " "; a template substitution that rendered to an empty string; a YAML multiline block scalar that collapsed to spaces.

Common situations: Placeholder tasks in a spec template; templating engines substituting an undefined variable to empty; hand-editing that deleted the body but left the quotes.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/e5430a901a532680. Report an issue: GitHub.