Hmbown/CodeWhale · error
Fleet task ' ' is write-capable but declares no…
Error message
Fleet task '{}' is write-capable but declares no workspace.writable_paths or metadata.coordination_contracts What it means
fleet_task_to_worker_spec_with_profiles refuses to launch a write-capable Fleet worker that has neither workspace.writable_paths nor metadata.coordination_contracts. A worker with write permissions must declare a bounded claim — where it may write or which contracts it coordinates under — so mutations cannot be unbounded (see fleet_write_roots / fleet_coordination_contracts).
Solutions
- Add `workspace.writable_paths` entries (repo-relative paths) to the task spec.
- Add a `metadata.coordination_contracts` array (at most 16 string entries) to the task spec.
- Set permissions.write to false if the task should not write at all.
- Use an agent profile that contributes the bounded write claim for this role.
Example fix
// before [tasks.refactor] permissions.write = true // after [tasks.refactor] permissions.write = true [tasks.refactor.workspace] writable_paths = ["src/refactor/"]
Defensive patterns
Strategy: validation
Validate before calling
if task.permissions.write && task.workspace.writable_paths.is_empty() && task.metadata.get("coordination_contracts").is_none() {
return Err("write-capable task needs writable_paths or coordination_contracts");
} Prevention
- Pair every write-enabled role with an explicit bounded claim.
- Default write permissions off unless a claim is defined.
- Review task templates after permission changes.
When it happens
Trigger: Building a worker spec from a FleetTaskSpec whose runtime_profile.permissions.write is true while fleet_write_roots(task_spec) returns an empty list and fleet_coordination_contracts(task_spec) returns an empty vec — i.e. no writable_paths in workspace config and no coordination_contracts metadata key.
Common situations: Defining a fleet task with a write-enabled role but forgetting `workspace.writable_paths`; copying a read-only task template and flipping permissions.write without adding a claim; profiles where the claim lives only in the parent profile and the task spec omits it.
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
- fleet task ' ' is write-capable but declares no…
- agent profile may not disable approval_required
- agent profile may not request allow_shell=true
- agent profile may not request trust=true
- agent profile tools.posture= would widen permissions; use…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/59d1bca522f399a9.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/fleet/worker_runtime.rs:453
requested_runtime.provider = explicit_fleet_provider_id(agent_profile);
if let Some(reasoning_effort) = effective_fleet_reasoning_effort(agent_profile) {
requested_runtime.reasoning_effort = Some(reasoning_effort);
}
if let Some(agent_profile) = agent_profile
&& let Some(profile_depth) = agent_profile.profile.delegation.max_spawn_depth
{
requested_runtime.max_spawn_depth = requested_runtime.max_spawn_depth.min(profile_depth);
}
let runtime_profile = parent_runtime_profile
.map(|parent| parent.derive_child(&requested_runtime))
.unwrap_or(requested_runtime);
let writable_roots = fleet_write_roots(task_spec)?;
let coordination_contracts = fleet_coordination_contracts(task_spec)?;
if runtime_profile.permissions.write
&& writable_roots.is_empty()
&& coordination_contracts.is_empty()
{
bail!(
"Fleet task '{}' is write-capable but declares no workspace.writable_paths or metadata.coordination_contracts",
task_spec.id
);
}
let session_name = format!("fleet-{}-{}", worker_id, task_spec.id);
let launch_manifest = ChildLaunchManifest {
owner_session: run_id.to_string(),
child_id: worker_id.to_string(),
profile: runtime_profile.clone(),
prompt: objective.clone(),
cwd: Some(workspace.display().to_string()),
worktree: worker_workspace_is_isolated(coordination_workspace, workspace),
writable_roots,
writable_files: Vec::new(),
coordination_contracts,
expected_artifact: None,
deliverables: Vec::new(),
resume_identity: Some(session_name.clone()),View on GitHub (pinned to 73e0f67d83)