Hmbown/CodeWhale · error

duplicate fleet task id

Error message

duplicate fleet task id {}

What it means

Task ids within a fleet task spec must be unique. validate_task_spec_document (crates/tui/src/fleet/task_spec.rs:165) tracks ids in a BTreeSet and bails on the first repeated task id, because ids identify tasks and workers within a run.

Solutions

  1. Give each [[tasks]] block a distinct id
  2. If tasks were meant to be variants, append a suffix (build-1, build-2)
  3. Search the spec for duplicate `id = "..."` values under [tasks]

Example fix

# before
[[tasks]]
id = "build"
[[tasks]]
id = "build"
# after
[[tasks]]
id = "build"
[[tasks]]
id = "test"
Defensive patterns

Strategy: validation

Validate before calling

let mut ids = std::collections::BTreeSet::new();
for t in &doc.tasks {
    if !ids.insert(t.id.clone()) {
        return Err(format!("duplicate task id: {}", t.id));
    }
}

Try / catch

match load_task_spec_document(path) {
    Ok(doc) => doc,
    Err(e) if e.to_string().contains("duplicate fleet task id") => {
        eprintln!("{}: rename one of the duplicate task ids", path.display());
        return;
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: A spec document contains two or more [[tasks]] blocks with the same `id`; detected during load_task_spec_document or create_queued_run_with_descriptor.

Common situations: Copy-pasting a task block to create a variant and forgetting to change the id; generated specs where an id template does not include an index.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/a8875ad1875a4f44. Report an issue: GitHub.

Appendix: source

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

    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.security_policy.is_some() {
        bail!(
            "fleet task spec security_policy is a legacy compatibility field, not executable Fleet identity; configure trust, secrets, approvals, sandboxing, and tool authority through Runtime policy"
        );
    }
    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())?;
        if task
            .metadata
            .contains_key(super::worker_runtime::FROZEN_FLEET_MEMBER_METADATA_KEY)
        {
            bail!(
                "fleet task {} metadata key {} is reserved for the durable Runtime selection receipt",
                task.id,

View on GitHub (pinned to 73e0f67d83)