Hmbown/CodeWhale · error · anyhow::Error
Tool cannot prove a bounded file target or read-only…
Error message
Tool {name} cannot prove a bounded file target or read-only execution while peers are writing in this shared checkout (blocking peers: {}). Use a bounded write tool, a proven read-only command, or bash with read_only=true for analysis under native enforcement. Executable work that needs writes requires worktree isolation. Disjoint write_roots alone do not constrain arbitrary code. What it means
While another agent holds a shared write claim in the same checkout, a tool call from this sub-agent could not prove it is either a bounded file write or a read-only execution, and live blocking peers exist. The library refuses unverifiable operations under concurrent shared writes because disjoint write_roots cannot constrain arbitrary code execution; work that writes must use worktree isolation.
Solutions
- Use a bounded write tool (which takes a scoped claim) instead of arbitrary execution.
- Re-run the command as a provable read-only command, or set `read_only: true` on the bash input for pure analysis.
- Wait for blocking peers to release their shared write claims, then retry.
- Move write-needing executable work into an isolated worktree and re-dispatch there.
Example fix
// before
{"tool":"bash","input":{"command":"cargo test foo -- --nocapture"}}
// after (analysis under native enforcement)
{"tool":"bash","input":{"command":"cargo test foo -- --nocapture","read_only":true}} Defensive patterns
Strategy: validation
Validate before calling
if coordination.live_peer_shared_write_claim_owners(me).len() > 0
&& !is_bounded_write(name)
&& !is_provably_readonly(name, &input)
{
// defer or isolate before calling
} Type guard
fn safe_under_shared_writes(name: &str, input: &Value) -> bool {
is_bounded_write_tool(name)
|| input.get("read_only").and_then(Value::as_bool).unwrap_or(false)
|| codewhale_execpolicy::command_safety::is_readonly_command(
input.get("command").and_then(Value::as_str).unwrap_or(""))
} Try / catch
match result {
Err(e) if e.to_string().contains("blocking peers:") => {
// wait for peer claims to clear or retry with read_only=true
}
other => other?,
} Prevention
- Check shared write claims before invoking non-bounded tools in shared checkouts.
- Prefer bounded write tools or read_only=true bash during concurrent sessions.
- Use worktree isolation for executable work that writes.
- Do not rely on disjoint write_roots to sandbox arbitrary code.
When it happens
Trigger: A peer sub-agent holds a live shared write claim (`live_peer_shared_write_claim_owners` non-empty) and this agent invokes a tool (typically bash without read_only=true) that neither mutates a bounded path nor passes the read-only command proof.
Common situations: Multiple agents sharing one workspace checkout where one is editing while another runs arbitrary shell; running build/test commands with extra args during a peer's write session; write_roots configured expecting isolation that the enforcer does not trust for unbounded tools.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- child wall-time budget exhausted
- Write tool did not expose a bounded repo-relative target…
- Agent continuation target is no longer retained
- Agent continuation target is outside the active session
- Agent not found
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/3838b337d6038d5d.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/subagent/mod.rs:17639
ToolCapability::WritesFiles
| ToolCapability::ExecutesCode
| ToolCapability::Network
)
})))
}))
{
let manager = self.coordination_manager.read().await;
// Only a *contended* shared checkout needs this gate. The claim
// exists so concurrent children cannot overwrite each other; a lone
// writer has no peer to collide with, and blocking it there bought
// no safety while making a builder unable to run ordinary shell
// work in the workspace the operator actually watches — worktree
// isolation "fixes" that by writing somewhere they never see.
if manager.shared_write_claim(&self.owner_agent_id).is_some() {
let blocking_peers =
manager.live_peer_shared_write_claim_owners(&self.owner_agent_id);
if !blocking_peers.is_empty() {
return Err(anyhow!(
"Tool {name} cannot prove a bounded file target or read-only execution while peers are writing in this shared checkout (blocking peers: {}). Use a bounded write tool, a proven read-only command, or bash with read_only=true for analysis under native enforcement. Executable work that needs writes requires worktree isolation. Disjoint write_roots alone do not constrain arbitrary code.",
blocking_peers.join(", ")
));
}
}
}
let context = self
.registry
.context()
.clone()
.with_owner_agent(self.owner_agent_id.clone(), self.owner_agent_name.clone());
let observed_paths = if scope_aware_write {
mutation_paths(name, &input)?
} else {
Vec::new()
};
let outcome = self
.registryView on GitHub (pinned to 433685b202)