Hmbown/CodeWhale · error

write-capable Fleet worker

Error message

write-capable Fleet worker '{}' has no launch manifest

What it means

When building a worker's ToolAuthorityEnvelope, a worker whose runtime profile grants write permissions must carry a launch manifest that scopes its writable roots/files and coordination contracts. A write-capable spec without a launch manifest cannot be safely constrained, so authority construction refuses to proceed.

Solutions

  1. Attach the launch manifest to the AgentWorkerSpec before starting a write-capable worker.
  2. If the worker is not supposed to write, set runtime_profile.permissions.write = false so the manifest is unnecessary.
  3. Fix the spec builder/template so write-capable workers always generate a manifest.

Example fix

// before
let spec = AgentWorkerSpec { worker_id: "w1".into(), runtime_profile: prof_with_write, launch_manifest: None, .. };
// after
let spec = AgentWorkerSpec { worker_id: "w1".into(), runtime_profile: prof_with_write, launch_manifest: Some(manifest), .. };
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_manifest(spec: &AgentWorkerSpec) -> Result<()> {
    if spec.runtime_profile.permissions.write {
        anyhow::ensure!(spec.launch_manifest.is_some(), "write worker needs launch manifest");
    }
    Ok(())
}

Type guard

fn has_write_manifest(spec: &AgentWorkerSpec) -> bool {
    !spec.runtime_profile.permissions.write || spec.launch_manifest.is_some()
}

Try / catch

match build_worker_exec_command(&spec, &task) {
    Err(e) if e.to_string().contains("no launch manifest") => {
        log::error!("worker {} requested write authority without a manifest", spec.worker_id);
        // reject the spec rather than downgrading silently
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling `authority_envelope_for_worker` (via build_worker_exec_command_with_launch_spec or start_worker_task) with an AgentWorkerSpec whose `runtime_profile.permissions.write` is true but whose `launch_manifest` is None.

Common situations: A worker spec built programmatically set permissions.write = true but never attached the launch manifest; a verifier-spec or task template omitted the manifest while requesting write access; config migration dropped the manifest field.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at crates/tui/src/fleet/executor.rs:220

) -> Option<u32> {
    match (task_max_steps(task_spec), exec_config.max_turns) {
        (Some(task_max_steps), fleet_max_turns) if fleet_max_turns > 0 => {
            Some(task_max_steps.min(fleet_max_turns))
        }
        (Some(task_max_steps), _) => Some(task_max_steps),
        (None, fleet_max_turns) if fleet_max_turns > 0 => Some(fleet_max_turns),
        (None, _) => None,
    }
}

pub(crate) fn authority_envelope_for_worker(
    spec: &AgentWorkerSpec,
    task_spec: &FleetTaskSpec,
) -> Result<ToolAuthorityEnvelope> {
    let (authority, writable_roots, writable_files, coordination_contracts) =
        if spec.runtime_profile.permissions.write {
            let manifest = spec.launch_manifest.as_ref().ok_or_else(|| {
                anyhow::anyhow!(
                    "write-capable Fleet worker '{}' has no launch manifest",
                    spec.worker_id
                )
            })?;
            (
                ToolMutationAuthority::ScopedWrite,
                super::worker_runtime::fleet_runtime_write_roots(task_spec)?,
                manifest.writable_files.clone(),
                manifest.coordination_contracts.clone(),
            )
        } else {
            (
                ToolMutationAuthority::ReadOnly,
                Vec::new(),
                Vec::new(),
                Vec::new(),
            )
        };

View on GitHub (pinned to 73e0f67d83)