{"record":{"id":"44d6a438bbd1f0c0","repo":"ruvnet/ruflo","slug":"capability-capability-id-is-not-delegatable","errorCode":null,"errorMessage":"Capability ${capability.id} is not delegatable","messagePattern":"Capability (.+?) is not delegatable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/guidance/src/capabilities.ts","lineNumber":229,"sourceCode":"    return restricted;\n  }\n\n  /**\n   * Delegate a capability to another agent.\n   *\n   * Creates a child capability with the new grantedTo agent. The parent\n   * capability must have delegatable=true. Optional further restrictions\n   * can be applied during delegation.\n   *\n   * @throws Error if the capability is not delegatable\n   */\n  delegate(\n    capability: Capability,\n    toAgentId: string,\n    restrictions?: Partial<Capability>,\n  ): Capability {\n    if (!capability.delegatable) {\n      throw new Error(\n        `Capability ${capability.id} is not delegatable`\n      );\n    }\n\n    if (capability.revoked) {\n      throw new Error(\n        `Cannot delegate revoked capability ${capability.id}`\n      );\n    }\n\n    if (capability.expiresAt !== null && capability.expiresAt <= Date.now()) {\n      throw new Error(\n        `Cannot delegate expired capability ${capability.id}`\n      );\n    }\n\n    const delegated: Capability = {\n      ...capability,","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/guidance/src/capabilities.ts#L211-L247","documentation":"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).","triggerScenarios":"Calling `delegate(cap, agentB)` on a capability granted without `delegatable: true`; composing workflows that assume any capability can be handed to a sub-agent.","commonSituations":"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.","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"],"exampleFix":"// before\nconst child = authority.delegate(parentCap, 'agent-b'); // parentCap.delegatable === false → throws\n\n// after\n// grantor re-issues with delegation allowed:\nconst parentCap = authority.grant({ ..., delegatable: true });\nconst child = authority.delegate(parentCap, 'agent-b');","handlingStrategy":"validation","validationCode":"if (!capability.delegatable) {\n  // request a delegatable re-grant or act directly — do not call delegate()\n}","typeGuard":"const isDelegatable = (c: Capability): boolean =>\n  c.delegatable === true && c.revoked !== true &&\n  (c.expiresAt === null || c.expiresAt > Date.now());","tryCatchPattern":null,"preventionTips":["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"],"tags":["capabilities","authorization","delegation","guidance","least-privilege"],"backgroundTag":"permission-not-delegatable","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}