Hmbown/CodeWhale · error · anyhow::Error
agent action=claim widens an enforced write scope, and the…
Error message
agent action=claim widens an enforced write scope, and the Fleet role `{role}` has no write authority to widen. Use an `implement` or `general` role. What it means
`agent action=claim` widens an enforced write scope (claiming work items). A Fleet role without write authority cannot widen any scope, so when the action gate `agent_action_permitted("claim")` fails, the dispatch layer rejects the call before it runs, independent of what the role's catalog withheld.
Solutions
- Re-spawn the worker with an `implement` or `general` role that has write authority.
- Have the read-only worker request the claim through the parent agent instead of calling `agent action=claim` itself.
- Verify the input action field actually means claim (check `ACTION_ALIASES`) and correct it if the worker intended a different action.
- Grant claim permission to the role in fleet configuration if this is an intended workflow change.
Example fix
// before
// scout role:
Agent.call({ action: "claim", task_id: 42 })
// after
// delegate to implement role or ask parent to claim:
Agent.call({ action: "claim", task_id: 42 }) // run by an 'implement' role Defensive patterns
Strategy: validation
Validate before calling
const action = parseAgentAction(input);
if (action === 'claim' && !roleCanWrite(agentType)) {
throw new Error('claim requires implement/general role');
} Type guard
const hasWriteAuthority = (role) => ['implement','general'].includes(role);
Try / catch
try { agent.call(input); } catch (e) { if (String(e).includes('no write authority to widen')) { parentClaim(taskId); } } Prevention
- Only emit agent action=claim from roles with write authority
- Have read-only workers request claims through the parent
- Document which fleet roles may claim work-graph items in delegation prompts
When it happens
Trigger: A sub-agent whose `agent_type` lacks write authority (e.g. scout, reviewer) issues `agent` with `action=claim`, and `parse_agent_tool_action` resolves it to `AgentToolAction::Claim` while `agent_action_permitted("claim")` returns false.
Common situations: A read-only worker tries to claim a work-graph item; the prompt template includes claim instructions written for implement roles; action alias parsing maps an ambiguous input onto `claim`.
Understand the failure class
Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.
Related errors
- Tool is not available to this read-only worker because its…
- append_allow_rules only accepts action = "allow"
- Codewhale credentials directory must be owned by the…
- Codewhale-owned credential file must be singly linked…
- Codewhale-owned xAI OAuth storage owner is not the current…
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/b59bd3073c3951f6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/subagent/mod.rs:17504
}
let action = input.get("action").and_then(Value::as_str);
if matches!(&self.agent_type, FleetRole::Scout | FleetRole::Reviewer)
&& name == "Web"
&& !matches!(action, Some("search" | "fetch"))
{
return Err(anyhow!(
"Tool Web is limited to search/fetch in the read-only evidence profile"
));
}
// Catalog shaping is not authority. `agent` clears both name-keyed
// gates below by design, so the per-action gate has to be repeated
// here or a hand-written call would reach an action the role's own
// catalog withheld.
if name == "agent"
&& matches!(parse_agent_tool_action(&input), Ok(AgentToolAction::Claim))
&& !self.agent_action_permitted("claim")
{
return Err(anyhow!(
"agent action=claim widens an enforced write scope, and the Fleet role `{role}` has no write authority to widen. Use an `implement` or `general` role.",
role = self.agent_type.as_str()
));
}
let family_action_allowed = if !Self::ACTION_ALIASES
.iter()
.any(|(family, _, _)| *family == name)
{
true
} else if let Some(action) = action {
self.is_action_allowed(name, action)
} else {
self.allowed_tools
.as_ref()
.is_none_or(|list| list.iter().any(|allowed| allowed == name))
};
if !self.is_tool_allowed(name) || !family_action_allowed {
return Err(anyhow!("Tool {name} not allowed for this sub-agent"));View on GitHub (pinned to 433685b202)