{"record":{"id":"f7c360548c044af0","repo":"mastra-ai/mastra","slug":"agent-delegation-hook-failed","errorCode":"AGENT_DELEGATION_HOOK_FAILED","errorMessage":"AGENT_DELEGATION_HOOK_FAILED","messagePattern":"AGENT_DELEGATION_HOOK_FAILED","errorType":"error_code","errorClass":"MastraError","httpStatus":null,"severity":"error","filePath":"packages/core/src/agent/agent.ts","lineNumber":5010,"sourceCode":"            // failure, so the failure path never re-invokes it.\n            let completeHookInvoked = false;\n\n            // Call onDelegationStart before resolving the sub-agent's runtime\n            // config so mutations of the delegated run's context in the hook\n            // are visible to version, model, and default-options resolution\n            // below. Rejection handling happens after resolution because the\n            // rejection path needs the resolved model version and memory config.\n            let startResult: DelegationStartResult | void | undefined;\n            if (delegation?.onDelegationStart) {\n              try {\n                startResult = await delegation.onDelegationStart(delegationStartContext);\n              } catch (hookError) {\n                const error = recordHookError('onDelegationStart', hookError, 'onDelegationStart hook error');\n                // Fail closed when configured: the delegation never started, so\n                // this throws directly rather than routing through\n                // onDelegationComplete. Otherwise continue with original values.\n                if (hookErrorStrategy === 'throw') {\n                  throw new MastraError(\n                    {\n                      id: 'AGENT_DELEGATION_HOOK_FAILED',\n                      domain: ErrorDomain.AGENT,\n                      category: ErrorCategory.USER,\n                      details: {\n                        agentName: this.name,\n                        subAgentName: agent.name ?? agent.id,\n                        hook: 'onDelegationStart',\n                        runId: runId || '',\n                      },\n                    },\n                    error,\n                  );\n                }\n              }\n            }\n\n            // Resolve versioned sub-agent if a version override exists on the","sourceCodeStart":4992,"sourceCodeEnd":5028,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/agent/agent.ts#L4992-L5028","documentation":"A MastraError (id AGENT_DELEGATION_HOOK_FAILED) thrown when a sub-agent's `onDelegationStart` hook throws AND the agent's hook error strategy is configured to 'throw' (fail-closed). Because the delegation never started, the error is raised directly instead of routing through `onDelegationComplete`. With a non-throw strategy the hook error is only logged and delegation proceeds.","triggerScenarios":"Multi-agent (network/delegation) invocation where a sub-agent has an `onDelegationStart` lifecycle hook registered, the hook callback throws, and hookErrorStrategy === 'throw' on the delegation configuration.","commonSituations":"Hooks that call external audit/telemetry services which are unreachable; hooks referencing request context fields that are absent in delegation calls; typo'd or version-mismatched hook signatures causing a TypeError inside the hook.","solutions":["Fix the code inside the sub-agent's `onDelegationStart` hook so it does not throw (the wrapped hookError message identifies the root cause)","Set the hook error strategy to a non-throwing value (e.g. 'continue'/'log') if a failed hook should not abort delegation","Add try/catch inside the hook to swallow/log non-critical failures","Validate any requestContext values the hook reads are provided for delegation calls"],"exampleFix":"// before\nhooks: { onDelegationStart: async (ctx) => { await auditService.log(ctx); } }\n// after\nhooks: { onDelegationStart: async (ctx) => { try { await auditService.log(ctx); } catch (e) { logger.warn('audit failed', e); } } }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isDelegationHookError(e) {\n  return e instanceof Error && 'id' in e && e.id === 'AGENT_DELEGATION_HOOK_FAILED';\n}","tryCatchPattern":"try {\n  await networkDelegate(...);\n} catch (e) {\n  if (e?.id === 'AGENT_DELEGATION_HOOK_FAILED') {\n    logger.error('delegation blocked by onDelegationStart hook', e.details);\n    return { status: 'delegation-blocked' };\n  }\n  throw e;\n}","preventionTips":["Wrap hook bodies in try/catch and log instead of throwing for non-critical failures","Only use hookErrorStrategy 'throw' when failing the delegation is truly required","Ensure hooks don't assume requestContext fields absent during delegation calls","Monitor hook errors to catch broken audit/telemetry dependencies early"],"tags":["agent","delegation","lifecycle-hook","multi-agent","fail-closed"],"backgroundTag":"lifecycle-hook-threw","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}