{"record":{"id":"1472ddaa57124ae3","repo":"can1357/oh-my-pi","slug":"cannot-spawn-another-agent-at-task-depth-taskdep","errorCode":null,"errorMessage":"Cannot spawn another agent at task depth ${taskDepth}; maximum depth is ${maxDepth}.","messagePattern":"Cannot spawn another agent at task depth (.+?); maximum depth is (.+?)\\.","errorType":"validation","errorClass":"StructuredSubagentError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/task/structured-subagent.ts","lineNumber":219,"sourceCode":"function assertPlanControlsAllowed(request: StructuredSubagentRequest, planMode: boolean): void {\n\tif (!planMode) return;\n\tconst isolation = request.isolation;\n\tif (\n\t\tisolation &&\n\t\t(Object.hasOwn(isolation, \"requested\") || Object.hasOwn(isolation, \"apply\") || Object.hasOwn(isolation, \"merge\"))\n\t) {\n\t\tthrow new StructuredSubagentError(\n\t\t\t\"preflight\",\n\t\t\t\"Subagent isolation, apply, and merge controls are unavailable in plan mode.\",\n\t\t);\n\t}\n}\n\nfunction assertDepthAndSpawnAllowed(request: StructuredSubagentRequest, agentName: string): void {\n\tconst taskDepth = request.session.taskDepth ?? 0;\n\tconst maxDepth = request.session.settings.get(\"task.maxRecursionDepth\") ?? 2;\n\tif (!canSpawnAtDepth(maxDepth, taskDepth)) {\n\t\tthrow new StructuredSubagentError(\n\t\t\t\"preflight\",\n\t\t\t`Cannot spawn another agent at task depth ${taskDepth}; maximum depth is ${maxDepth}.`,\n\t\t);\n\t}\n\tconst blockedAgent = request.blockedAgent ?? $env.PI_BLOCKED_AGENT;\n\tif (blockedAgent && blockedAgent === agentName) {\n\t\tthrow new StructuredSubagentError(\n\t\t\t\"preflight\",\n\t\t\t`Cannot spawn ${blockedAgent} agent from within itself (recursion prevention). Use a different agent type.`,\n\t\t);\n\t}\n\tconst spawnPolicy = resolveSpawnPolicy(request.session.getSessionSpawns());\n\tif (!spawnPolicy.enabled || (spawnPolicy.allowedAgents !== null && !spawnPolicy.allowedAgents.includes(agentName))) {\n\t\tthrow new StructuredSubagentError(\n\t\t\t\"preflight\",\n\t\t\t`Cannot spawn '${agentName}'. Allowed: ${spawnPolicy.allowedErrorText}`,\n\t\t);\n\t}","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/task/structured-subagent.ts#L201-L237","documentation":"Thrown in preflight when the current task depth (`request.session.taskDepth`, default 0) already equals or exceeds the configured `task.maxRecursionDepth` setting (default 2). The library caps how deeply subagents may nest to prevent runaway recursion. `canSpawnAtDepth` returns false and `assertDepthAndSpawnAllowed` raises a preflight StructuredSubagentError.","triggerScenarios":"A subagent (depth 1) or deeper descendant tries to spawn another subagent when `taskDepth >= task.maxRecursionDepth`; e.g. depth 2 with the default max of 2, or depth 1 with maxRecursionDepth set to 1.","commonSituations":"Deeply nested agent workflows (agent spawns agent spawns agent); lowering `task.maxRecursionDepth` in settings below the existing nesting; recursive task-decomposition prompts that let the subagent re-invoke the task tool.","solutions":["Flatten the workflow: have the deepest subagent return results instead of spawning more agents","Raise `task.maxRecursionDepth` in settings (e.g. to 3) if deeper nesting is intentional","Check `session.taskDepth` before calling and skip nested spawning at the limit"],"exampleFix":"// settings before\n{ \"task.maxRecursionDepth\": 1 }\n// after\n{ \"task.maxRecursionDepth\": 2 }","handlingStrategy":"validation","validationCode":"const depth = session.taskDepth ?? 0;\nconst maxDepth = session.settings.get(\"task.maxRecursionDepth\") ?? 2;\nif (depth >= maxDepth) return fallbackResult(); // skip spawning\nawait task(request);","typeGuard":null,"tryCatchPattern":"try {\n  await task(req);\n} catch (e) {\n  if (e instanceof StructuredSubagentError && e.message.includes(\"maximum depth\")) {\n    return doWorkInline(); // handle without nesting\n  }\n  throw e;\n}","preventionTips":["Track taskDepth in nested agent prompts and stop spawning near the limit","Keep task.maxRecursionDepth consistent across environments","Design workflows to be shallow; prefer returning data over spawning more agents"],"tags":["subagent","recursion","depth-limit","configuration"],"backgroundTag":"recursion-depth-exceeded","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}