{"record":{"id":"5c616a862612cc8f","repo":"Hmbown/CodeWhale","slug":"cannot-resume-agent-agent-id-sub-agent-depth-li","errorCode":null,"errorMessage":"Cannot resume agent {agent_id}: sub-agent depth limit reached (current {}, max {})","messagePattern":"Cannot resume agent (.+?): sub-agent depth limit reached \\(current (.+?), max (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/subagent/mod.rs","lineNumber":5744,"sourceCode":"            (\n                agent.agent_type.clone(),\n                build_resume_prompt(&agent.prompt, checkpoint, followup_text),\n                agent.assignment.clone(),\n                agent.allowed_tools.clone(),\n                agent.model.clone(),\n                agent.fork_context,\n                agent.workspace.clone(),\n                claim,\n                preserved_profile,\n                child_route,\n            )\n        };\n        // Resume runs at child depth with a detached cancellation token, the\n        // same seam a fresh spawn uses; fail closed on the depth ceiling.\n        // Checked on the parent runtime before derivation, matching the\n        // fresh-spawn order (would_exceed_depth at the spawn seam).\n        if runtime.would_exceed_depth() {\n            return Err(anyhow!(\n                \"Cannot resume agent {agent_id}: sub-agent depth limit reached (current {}, max {})\",\n                runtime.spawn_depth,\n                runtime.max_spawn_depth\n            ));\n        }\n        let runtime = runtime.background_runtime();\n        // Resume in the interrupted child's workspace, not the caller's\n        // (worktree/cwd children must not resume in the parent directory).\n        let mut runtime = runtime;\n        runtime.context.workspace = workspace;\n        let options = SubAgentSpawnOptions {\n            name: None, // the old session name stays owned by the terminal record\n            model: Some(model),\n            model_route: None,\n            child_route,\n            nickname: None,\n            fork_context,\n            write_claim: claim.as_ref().map(|(claim, _)| claim.clone()),","sourceCodeStart":5726,"sourceCodeEnd":5762,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/tools/subagent/mod.rs#L5726-L5762","documentation":"Resuming an interrupted child counts as a new spawn at child depth, and the manager fails closed when runtime.would_exceed_depth() is true — the parent's spawn_depth is already at max_spawn_depth. The check runs on the parent runtime before deriving the background runtime, mirroring the fresh-spawn seam so an infinite chain of nested resumes is impossible. The message reports both current and maximum depth.","triggerScenarios":"Resuming the deepest agent in a nested tree (child of child of child) when the chain already sits at the maximum spawn depth; orchestration where a resumed agent itself resumes another agent, walking depth upward each time; low max_spawn_depth configured for the session.","commonSituations":"Recursive/deeply nested agent workflows (agent spawns researcher which spawns sub-researcher) followed by a resume of the leaf; tight depth ceilings set to prevent runaway nesting; resumes issued from within already-deep continuation chains.","solutions":["Flatten the orchestration: move the resumed work to a shallower/top-level agent instead of resuming the deepest child","Raise the configured maximum sub-agent spawn depth if the nesting is legitimate","Spawn a fresh top-level agent that receives the interrupted child's checkpoint content as prompt context"],"exampleFix":"// before\nlet resumed = manager.resume_from_checkpoint_with_policy(\n    handle, runtime, &deep_child_id, &text, policy)?;\n\n// after\nif runtime.would_exceed_depth() {\n    // resume would exceed the ceiling: relay the work at top level instead\n    return spawn_top_level_with_context(manager, &deep_child_id, &text).await;\n}\nlet resumed = manager.resume_from_checkpoint_with_policy(\n    handle, runtime, &deep_child_id, &text, policy)?;","handlingStrategy":"validation","validationCode":"// Fail fast before the resume seam when the ceiling is already hit.\nif runtime.would_exceed_depth() {\n    return plan_shallow_resume(&agent_id); // relay work at a shallower level\n}","typeGuard":"fn resume_within_depth(runtime: &SubAgentRuntime) -> bool {\n    !runtime.would_exceed_depth()\n}","tryCatchPattern":"Catch 'sub-agent depth limit reached' and do not retry at the same depth: either raise the configured max depth or relay the checkpoint content into a fresh top-level agent.","preventionTips":["Track spawn depth in your orchestration bookkeeping and refuse to queue resumes that would exceed the ceiling","Flatten deep agent trees during design; resume at the shallowest level that has the needed context","Size max_spawn_depth to the workflow's real nesting before running deep fan-outs"],"tags":["subagent","rust","depth-limit","recursion","resource-limits","resume"],"backgroundTag":"recursion-limit-exceeded","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}