Hmbown/CodeWhale · error
fleet task {} objective cannot be empty
Error message
fleet task {} objective cannot be empty What it means
The objective field of a fleet task is optional, but validate_task_spec_document requires that a present objective be non-blank after trimming. An empty objective is rejected because receipts and UI surfaces would otherwise render an explicitly empty goal with no way to distinguish it from an unset one.
Source
Thrown at crates/tui/src/fleet/task_spec.rs:131
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)?;
}
Ok(())
}
fn validate_fleet_identity(field: &str, value: &str) -> Result<()> {
if value.is_empty() {View on GitHub (pinned to 0c42157ee5)
Solutions
- Either delete the objective key from the task or give it real text
- Configure your serializer to skip None/empty optional fields (serde skip_serializing_if on the producer side)
- Check the task id in the error message to find the offending block quickly
Example fix
// before
{ "id": "t1", "name": "t1", "instructions": "...", "objective": "" }
// after
{ "id": "t1", "name": "t1", "instructions": "...", "objective": "Ship the fix" } Defensive patterns
Strategy: validation
Validate before calling
fn objectives_ok(tasks: &[FleetTaskSpec]) -> bool {
tasks.iter()
.all(|t| t.objective.as_deref().map_or(true, |o| !o.trim().is_empty()))
} Type guard
function objectiveValid(t: { objective?: string }): boolean {
return t.objective === undefined || t.objective.trim().length > 0;
} Try / catch
if let Err(err) = load_task_spec_document(&path) {
if err.to_string().contains("objective cannot be empty") {
eprintln!("a task in {path:?} sets objective to blank - delete the key or fill it");
}
return Err(err);
} Prevention
- Configure serializers to skip empty optional fields (skip_serializing_if on the producer side)
- Prefer omitting optional fields over writing empty strings
- Test generated specs with a validator before launching fleet runs
When it happens
Trigger: A task containing "objective": "" or "objective": " ". Omitting the key entirely passes - only a present-but-blank value bails.
Common situations: Templates that always emit the objective key; editors clearing the text but leaving the field; serializers writing empty strings for unset optional strings.
Related errors
- fleet task {} instructions cannot be empty
- fleet {field} cannot be empty
- fleet task {task_id} tag cannot be empty
- agent profile {} {field} cannot be empty
- fleet task spec must include at least one task
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/9835f11aa06a813e.
Report an issue: GitHub.