Hmbown/CodeWhale · error

fleet task {task_id} {field} cannot be empty

Error message

fleet task {task_id} {field} cannot be empty

What it means

validate_worker_token checks the optional worker.loadout and worker.model_class fields of a task's worker profile. If present, a value must be non-blank after trimming; a whitespace-only string is rejected instead of silently dropping the override.

Source

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

    };
    validate_worker_token(
        task_id,
        "worker.agent_profile",
        worker.agent_profile.as_deref(),
    )?;
    validate_worker_token(task_id, "worker.loadout", worker.loadout.as_deref())?;
    validate_worker_token(task_id, "worker.model_class", worker.model_class.as_deref())?;
    validate_worker_model(task_id, worker.model.as_deref())?;
    Ok(())
}

fn validate_worker_token(task_id: &str, field: &str, value: Option<&str>) -> Result<()> {
    let Some(value) = value else {
        return Ok(());
    };
    let trimmed = value.trim();
    if trimmed.is_empty() {
        bail!("fleet task {task_id} {field} cannot be empty");
    }
    if trimmed != value || !trimmed.chars().all(is_worker_token_char) {
        bail!(
            "fleet task {task_id} {field} must be a simple token, not a path or provider/model id"
        );
    }
    Ok(())
}

fn is_worker_token_char(ch: char) -> bool {
    ch.is_ascii_alphanumeric() || matches!(ch, '-' | '_' | '.')
}

fn validate_worker_model(task_id: &str, value: Option<&str>) -> Result<()> {
    let Some(value) = value else {
        return Ok(());
    };
    let trimmed = value.trim();

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Remove the blank worker.loadout / worker.model_class key, or set a real token value
  2. Make your spec serializer omit keys whose value is empty
  3. Re-check the task id in the message to locate the failing worker block

Example fix

// before
{ "id": "t1", "instructions": "...", "worker": { "model_class": "" } }

// after
{ "id": "t1", "instructions": "...", "worker": { "model_class": "frontier" } }
// or drop the worker.model_class key entirely
Defensive patterns

Strategy: validation

Validate before calling

fn worker_tokens_ok(values: &[Option<&str>]) -> bool {
    values.iter().flatten().all(|v| !v.trim().is_empty())
}

Type guard

function optionalTokenOk(v: string | undefined): boolean {
  return v === undefined || v.trim().length > 0;
}

Try / catch

if let Err(err) = load_task_spec_document(&path) {
    if err.to_string().contains("cannot be empty") && err.to_string().contains("worker.") {
        eprintln!("{path:?}: blank worker.loadout/model_class - set a token or drop the key");
    }
    return Err(err);
}

Prevention

When it happens

Trigger: A task with "worker": { "loadout": "" } or "worker": { "model_class": " " }. Omitting the keys passes - only present-but-blank values bail.

Common situations: Spec templates that always emit both worker keys; editors clearing a loadout override; generators writing empty strings for unset optionals.

Related errors


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