{"record":{"id":"e5430a901a532680","repo":"Hmbown/CodeWhale","slug":"fleet-task-instructions-cannot-be-empty","errorCode":null,"errorMessage":"fleet task {} instructions cannot be empty","messagePattern":"fleet task (.+?) instructions cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/fleet/task_spec.rs","lineNumber":126,"sourceCode":"    };\n    let doc = parsed.into_document(fallback_name);\n    validate_task_spec_document(&doc)?;\n    Ok(doc)\n}\n\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    }","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/fleet/task_spec.rs#L108-L144","documentation":"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.","triggerScenarios":"A task with \"instructions\": \"\" or \"instructions\": \"   \"; a template substitution that rendered to an empty string; a YAML multiline block scalar that collapsed to spaces.","commonSituations":"Placeholder tasks in a spec template; templating engines substituting an undefined variable to empty; hand-editing that deleted the body but left the quotes.","solutions":["Write real instructions text for the task id named in the error","If templating, fail the build when a substitution produces an empty instructions value","Delete the task entirely if it is a leftover placeholder"],"exampleFix":"// before\n{ \"id\": \"lint\", \"name\": \"lint\", \"instructions\": \"\" }\n\n// after\n{ \"id\": \"lint\", \"name\": \"lint\", \"instructions\": \"Run cargo clippy --workspace and report warnings\" }","handlingStrategy":"validation","validationCode":"fn instructions_present(tasks: &[FleetTaskSpec]) -> bool {\n    tasks.iter().all(|t| !t.instructions.trim().is_empty())\n}","typeGuard":"function hasInstructions(t: { instructions: string }): boolean {\n  return t.instructions.trim().length > 0;\n}","tryCatchPattern":"if let Err(err) = load_task_spec_document(&path) {\n    if err.to_string().contains(\"instructions cannot be empty\") {\n        eprintln!(\"a task in {path:?} has blank instructions - fill or remove it\");\n    }\n    return Err(err);\n}","preventionTips":["Fail template expansion when an instructions substitution renders empty","Treat blank instructions as a build error in spec generators, not a default","Lint specs for whitespace-only required strings before commit"],"tags":["fleet","task-spec","instructions","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"}