Hmbown/CodeWhale · error

fleet {field} cannot be empty

Error message

fleet {field} cannot be empty

What it means

validate_fleet_identity is applied to every task id and worker id and rejects an empty string. Ids are filesystem- and ledger-facing keys, so a blank one can never be valid.

Source

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

        }
        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() {
        bail!("fleet {field} cannot be empty");
    }
    if value.len() > MAX_FLEET_ID_BYTES || !value.chars().all(is_worker_token_char) {
        bail!(
            "fleet {field} must be a simple ASCII token no longer than {MAX_FLEET_ID_BYTES} bytes"
        );
    }
    Ok(())
}

fn validate_fleet_name(field: &str, value: &str) -> Result<()> {
    if value.trim().is_empty() {
        bail!("fleet {field} cannot be empty");
    }
    if value.len() > MAX_FLEET_NAME_BYTES || value.chars().any(char::is_control) {
        bail!(
            "fleet {field} must be one printable line no longer than {MAX_FLEET_NAME_BYTES} bytes"
        );
    }

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Set a non-empty id on the entry named by the field prefix in the error ("task id" or "worker id")
  2. Fail template expansion when an id variable is empty
  3. Use the same slug everywhere for the logical unit so ids stay greppable

Example fix

// before
{ "id": "", "name": "build", "instructions": "..." }

// after
{ "id": "build", "name": "build", "instructions": "..." }
Defensive patterns

Strategy: validation

Validate before calling

fn ids_nonempty(entries: &[impl AsRef<str>]) -> bool {
    entries.iter().all(|e| !e.as_ref().is_empty())
}

Type guard

function isNonEmptyId(id: string): boolean {
  return id.length > 0;
}

Try / catch

if let Err(err) = load_task_spec_document(&path) {
    if err.to_string().contains("cannot be empty") {
        eprintln!("{path:?}: every task/worker entry needs a non-empty id");
    }
    return Err(err);
}

Prevention

When it happens

Trigger: A task or workers entry with "id": "" - the very first check in validate_fleet_identity fires before format or length checks.

Common situations: A generator emitting an empty id before assigning one; hand-editing that removed the id text; JSON built from a map with a blank key.

Related errors


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