{"record":{"id":"9835f11aa06a813e","repo":"Hmbown/CodeWhale","slug":"fleet-task-objective-cannot-be-empty","errorCode":null,"errorMessage":"fleet task {} objective cannot be empty","messagePattern":"fleet task (.+?) objective cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/fleet/task_spec.rs","lineNumber":131,"sourceCode":"\npub fn validate_task_spec_document(doc: &FleetTaskSpecDocument) -> Result<()> {\n    if doc.tasks.is_empty() {\n        bail!(\"fleet task spec must include at least one task\");\n    }\n    let mut ids = BTreeSet::new();\n    for task in &doc.tasks {\n        validate_fleet_identity(\"task id\", &task.id)?;\n        if !ids.insert(task.id.clone()) {\n            bail!(\"duplicate fleet task id {}\", task.id);\n        }\n        validate_fleet_name(&format!(\"task {} name\", task.id), &task.name)?;\n        if task.instructions.trim().is_empty() {\n            bail!(\"fleet task {} instructions cannot be empty\", task.id);\n        }\n        if let Some(objective) = &task.objective\n            && objective.trim().is_empty()\n        {\n            bail!(\"fleet task {} objective cannot be empty\", task.id);\n        }\n        validate_worker_profile(&task.id, task.worker.as_ref())?;\n        validate_tags(&task.id, &task.tags)?;\n        validate_workspace_requirements(task)?;\n    }\n    let mut worker_ids = BTreeSet::new();\n    for worker in &doc.workers {\n        validate_fleet_identity(\"worker id\", &worker.id)?;\n        if !worker_ids.insert(worker.id.clone()) {\n            bail!(\"duplicate fleet worker id {}\", worker.id);\n        }\n        validate_fleet_name(&format!(\"worker {} name\", worker.id), &worker.name)?;\n    }\n    Ok(())\n}\n\nfn validate_fleet_identity(field: &str, value: &str) -> Result<()> {\n    if value.is_empty() {","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/fleet/task_spec.rs#L113-L149","documentation":"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.","triggerScenarios":"A task containing \"objective\": \"\" or \"objective\": \"   \". Omitting the key entirely passes - only a present-but-blank value bails.","commonSituations":"Templates that always emit the objective key; editors clearing the text but leaving the field; serializers writing empty strings for unset optional strings.","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"],"exampleFix":"// before\n{ \"id\": \"t1\", \"name\": \"t1\", \"instructions\": \"...\", \"objective\": \"\" }\n\n// after\n{ \"id\": \"t1\", \"name\": \"t1\", \"instructions\": \"...\", \"objective\": \"Ship the fix\" }","handlingStrategy":"validation","validationCode":"fn objectives_ok(tasks: &[FleetTaskSpec]) -> bool {\n    tasks.iter()\n        .all(|t| t.objective.as_deref().map_or(true, |o| !o.trim().is_empty()))\n}","typeGuard":"function objectiveValid(t: { objective?: string }): boolean {\n  return t.objective === undefined || t.objective.trim().length > 0;\n}","tryCatchPattern":"if let Err(err) = load_task_spec_document(&path) {\n    if err.to_string().contains(\"objective cannot be empty\") {\n        eprintln!(\"a task in {path:?} sets objective to blank - delete the key or fill it\");\n    }\n    return Err(err);\n}","preventionTips":["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"],"tags":["fleet","task-spec","objective","validation","required-field"],"backgroundTag":"empty-required-field","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}