{"record":{"id":"0aefce3726ad9ed4","repo":"n8n-io/n8n","slug":"toolname-was-registered-without-a-runsubagent-c","errorCode":null,"errorMessage":"${toolName} was registered without a runSubAgent callback, and no host runner was provided. Register it on an Agent (for inline delegation) or pass runSubAgent.","messagePattern":"(.+?) was registered without a runSubAgent callback, and no host runner was provided\\. Register it on an Agent \\(for inline delegation\\) or pass runSubAgent\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/agents/src/runtime/tools/delegate-sub-agent-tool.ts","lineNumber":667,"sourceCode":"\t\t\tif (output.status === 'suspended') {\n\t\t\t\treturn await cascadeChildSuspension(ctx, request, output);\n\t\t\t}\n\t\t\treturn output;\n\t\t}\n\n\t\tconst childPathIndexKey = getChildPathIndexKey(ctx);\n\t\tconst childPathIndex = childPathIndexes.get(childPathIndexKey) ?? 0;\n\n\t\ttaskPath = createChildSubAgentTaskPath(input.taskName, childPathIndex);\n\t\tchildPathIndexes.set(childPathIndexKey, childPathIndex + 1);\n\n\t\trequest = createDelegateSubAgentRequest(input, ctx, taskPath, childPathIndex, options.policy);\n\n\t\tstartedAt = Date.now();\n\t\temitSubAgentStarted(ctx, request, startedAt);\n\t\tconst toolName = options.name ?? DELEGATE_SUB_AGENT_TOOL_NAME;\n\t\tif (!options.runSubAgent) {\n\t\t\tthrow new Error(\n\t\t\t\t`${toolName} was registered without a runSubAgent callback, and no host runner was provided. Register it on an Agent (for inline delegation) or pass runSubAgent.`,\n\t\t\t);\n\t\t}\n\t\tconst output = await options.runSubAgent(\n\t\t\trequest,\n\t\t\tcreateRunnerHelpers(ctx, request, options.name),\n\t\t);\n\t\temitSubAgentCompleted(ctx, request, output, startedAt);\n\t\tif (\n\t\t\toutput.status === 'suspended' &&\n\t\t\toptions.resumeSubAgent !== undefined &&\n\t\t\tisInterruptibleToolContext(ctx)\n\t\t) {\n\t\t\treturn await cascadeChildSuspension(ctx, request, output);\n\t\t}\n\t\treturn output;\n\t} catch (error) {\n\t\t// When the parent has a signal it is the authority: `isAbortError` also","sourceCodeStart":649,"sourceCodeEnd":685,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/agents/src/runtime/tools/delegate-sub-agent-tool.ts#L649-L685","documentation":"Thrown at runtime inside the delegate tool's handler when options.runSubAgent is falsy. The createDelegateSubAgentTool function creates a tool that needs a runner to actually execute the child agent. When registered on an Agent (via the Agent's delegate method), the Agent's build process injects runSubAgent automatically. If the tool is used standalone without that injection, the handler has no way to execute the child and fails.","triggerScenarios":"Creating a delegate tool with createDelegateSubAgentTool() and adding it to an agent via a path that bypasses the Agent's built-in delegate wiring (e.g. constructing the tool manually and pushing it into .tools()). Or passing the tool to a custom runtime that does not set runSubAgent.","commonSituations":"Building a custom agent class or runtime that does not extend the Agent's delegate registration. Extracting the tool for testing without mocking runSubAgent. Migrating from a manual tool registration pattern to the Agent builder without removing the old manual registration.","solutions":["Register the delegate tool through the Agent's .delegate() method instead of createDelegateSubAgentTool + .tools().","If using createDelegateSubAgentTool directly, pass a runSubAgent callback that invokes your host's child-agent runner.","Ensure the Agent's build() method runs before the tool is invoked (the build injects runSubAgent)."],"exampleFix":"// before\nconst tool = createDelegateSubAgentTool({});\nagent.tools([tool]); // runSubAgent never injected\n// after\nagent.delegate(); // Agent build injects runSubAgent automatically","handlingStrategy":"validation","validationCode":"// Ensure the delegate tool is registered through the Agent, not standalone:\nif (!options.runSubAgent && !registeredViaAgent) {\n  throw new Error('Delegate tool needs runSubAgent or Agent registration');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register delegate tools via Agent.delegate() so the build injects runSubAgent automatically.","Do not push createDelegateSubAgentTool() output into agent.tools() manually.","If using a host runner, always pass a runSubAgent callback to createDelegateSubAgentTool."],"tags":["delegate-tool","configuration","agent-build","runtime"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}