ruvnet/ruflo · error
Capability ${capability.id} is not delegatable
Error message
Capability ${capability.id} is not delegatable What it means
CapabilityAuthority.delegate() mints a child capability from a parent, but only if the parent was granted with `delegatable: true`. Delegatability is an explicit opt-in at grant time, not a default, so this error means the capability's issuer never allowed it to be passed on. It is the first of three parent-state checks (delegatable, not revoked, not expired).
Source
Thrown at v3/@claude-flow/guidance/src/capabilities.ts:229
return restricted;
}
/**
* Delegate a capability to another agent.
*
* Creates a child capability with the new grantedTo agent. The parent
* capability must have delegatable=true. Optional further restrictions
* can be applied during delegation.
*
* @throws Error if the capability is not delegatable
*/
delegate(
capability: Capability,
toAgentId: string,
restrictions?: Partial<Capability>,
): Capability {
if (!capability.delegatable) {
throw new Error(
`Capability ${capability.id} is not delegatable`
);
}
if (capability.revoked) {
throw new Error(
`Cannot delegate revoked capability ${capability.id}`
);
}
if (capability.expiresAt !== null && capability.expiresAt <= Date.now()) {
throw new Error(
`Cannot delegate expired capability ${capability.id}`
);
}
const delegated: Capability = {
...capability,View on GitHub (pinned to fa13ee4ad6)
Solutions
- Ask the original grantor to re-grant with `delegatable: true` (narrow actions/resources if needed)
- Skip delegation: have the parent capability's holder perform the action directly
- Mint a fresh capability for the target agent from the authority instead of delegating
Example fix
// before
const child = authority.delegate(parentCap, 'agent-b'); // parentCap.delegatable === false → throws
// after
// grantor re-issues with delegation allowed:
const parentCap = authority.grant({ ..., delegatable: true });
const child = authority.delegate(parentCap, 'agent-b'); Defensive patterns
Strategy: validation
Validate before calling
if (!capability.delegatable) {
// request a delegatable re-grant or act directly — do not call delegate()
} Type guard
const isDelegatable = (c: Capability): boolean => c.delegatable === true && c.revoked !== true && (c.expiresAt === null || c.expiresAt > Date.now());
Prevention
- Grant with delegatable: true only for capabilities intended to be passed on
- Keep delegation decision points checking the delegatable flag
- Treat least-privilege defaults as intentional; do not assume delegation works
When it happens
Trigger: Calling `delegate(cap, agentB)` on a capability granted without `delegatable: true`; composing workflows that assume any capability can be handed to a sub-agent.
Common situations: Default grants (least-privilege) omit delegatable; a security review tightened grants to non-delegatable and downstream delegation code now fails; capabilities granted by another team/service without delegation rights.
Related errors
- Cannot delegate revoked capability ${capability.id}
- Cannot delegate expired capability ${capability.id}
- Cannot compose capabilities with different scopes: "${cap1.s
- Cannot compose capabilities with different resources: "${cap
- scope-cannot-grow
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/44d6a438bbd1f0c0.
Report an issue: GitHub.