can1357/oh-my-pi · error · StructuredSubagentError
Subagent isolation, apply, and merge controls are unavailabl
Error message
Subagent isolation, apply, and merge controls are unavailable in plan mode.
What it means
This error is thrown during subagent preflight when a structured subagent request includes isolation controls (requested/apply/merge on the `isolation` object) while the session is in plan mode. Plan mode is read-only by design: spawning agents that create worktrees, apply changes, or merge results would violate it. `assertPlanControlsAllowed` (via `resolveEffectiveSubagentPolicy`) rejects any isolation object that sets any of those keys before the agent is spawned.
Source
Thrown at packages/coding-agent/src/task/structured-subagent.ts:208
function createPlanModeAgent(agent: AgentDefinition): AgentDefinition {
const tools = [...PLAN_MODE_TOOLS, ...(agent.tools ?? []).filter(tool => tool === "ast_grep")];
return {
...agent,
systemPrompt: `${planModeSubagentPrompt}\n\n${agent.systemPrompt}`,
tools,
spawns: undefined,
prewalk: undefined,
};
}
function assertPlanControlsAllowed(request: StructuredSubagentRequest, planMode: boolean): void {
if (!planMode) return;
const isolation = request.isolation;
if (
isolation &&
(Object.hasOwn(isolation, "requested") || Object.hasOwn(isolation, "apply") || Object.hasOwn(isolation, "merge"))
) {
throw new StructuredSubagentError(
"preflight",
"Subagent isolation, apply, and merge controls are unavailable in plan mode.",
);
}
}
function assertDepthAndSpawnAllowed(request: StructuredSubagentRequest, agentName: string): void {
const taskDepth = request.session.taskDepth ?? 0;
const maxDepth = request.session.settings.get("task.maxRecursionDepth") ?? 2;
if (!canSpawnAtDepth(maxDepth, taskDepth)) {
throw new StructuredSubagentError(
"preflight",
`Cannot spawn another agent at task depth ${taskDepth}; maximum depth is ${maxDepth}.`,
);
}
const blockedAgent = request.blockedAgent ?? $env.PI_BLOCKED_AGENT;
if (blockedAgent && blockedAgent === agentName) {
throw new StructuredSubagentError(View on GitHub (pinned to 9690622007)
Solutions
- Remove the `isolation` field (or the requested/apply/merge keys) from the subagent request while in plan mode
- Exit plan mode (accept the plan) before spawning an isolated subagent
- Guard the call site: only pass isolation controls when `session` is not in plan mode
Example fix
// before
await task({ agent: "researcher", isolation: { requested: true } });
// after
await task({ agent: "researcher" }); // plan mode: no isolation controls Defensive patterns
Strategy: validation
Validate before calling
if (sessionPlanMode && request.isolation && ("requested" in request.isolation || "apply" in request.isolation || "merge" in request.isolation)) {
throw new Error("Cannot use isolation controls in plan mode");
}
await task(request); Try / catch
try {
await task(req);
} catch (e) {
if (e instanceof StructuredSubagentError && e.stage === "preflight" && e.message.includes("plan mode")) {
const { isolation, ...rest } = req;
return task(rest); // retry without isolation
}
throw e;
} Prevention
- Only attach isolation options when the session is in execution mode
- Centralize subagent request construction so plan-mode calls cannot include isolation
- Test plan-mode paths of any workflow that spawns subagents
When it happens
Trigger: Calling the structured subagent (task tool) with `isolation: { requested: true }` (or `apply`/`merge` set, even to false via Object.hasOwn presence check) while the parent session is in plan mode.
Common situations: A main-agent prompt template that always attaches isolation options now running under plan mode; a user toggles plan mode mid-session and re-runs a previously valid task call; programmatic SDK callers reusing a request builder that hardcodes isolation settings.
Related errors
- agent() isolated apply failed for ${result.id}${summary ? `:
- agent() isolated nested patch apply failed for ${result.id}:
- Cannot spawn ${blockedAgent} agent from within itself (recur
- Unknown agent "${agentName}". Available: ${available}
- Invalid ${scope} output schema: ${error}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/1be41eb24037bc3b.
Report an issue: GitHub.