openclaw/openclaw · error
Batch nesting depth exceeds maximum of ${ACT_MAX_BATCH_DEPTH
Error message
Batch nesting depth exceeds maximum of ${ACT_MAX_BATCH_DEPTH} What it means
Thrown by executeSingleAction (extensions/browser/src/browser/pw-tools-core.interactions.execution.ts:56) when the recursive batch depth exceeds ACT_MAX_BATCH_DEPTH (defined as 5 in extensions/browser/src/browser/act-policy.ts). Batch actions may nest other batch actions; the executor caps recursion to prevent unbounded/stack-exhausting batch trees. A companion normalization pre-check in routes/agent.act.normalize.ts emits a friendlier message at the same threshold, so reaching the executor's throw usually means a batch bypassed normalization or was built after it.
Source
Thrown at extensions/browser/src/browser/pw-tools-core.interactions.execution.ts:56
type GuardedInteractionOptions,
hasInteractionNavigationPolicy,
interactionNavigationPolicy,
} from "./pw-tools-core.interactions.navigation.js";
import { closePageViaPlaywright, resizeViewportViaPlaywright } from "./pw-tools-core.snapshot.js";
const ACT_DOWNLOAD_MAX_DRAIN_MS = 1_000;
async function executeSingleAction(
action: BrowserActRequest,
cdpUrl: string,
targetId?: string,
evaluateEnabled?: boolean,
navigationPolicy: BrowserNavigationPolicyOptions = {},
depth = 0,
signal?: AbortSignal,
): Promise<unknown> {
if (depth > ACT_MAX_BATCH_DEPTH) {
throw new Error(`Batch nesting depth exceeds maximum of ${ACT_MAX_BATCH_DEPTH}`);
}
const effectiveTargetId = action.targetId ?? targetId;
switch (action.kind) {
case "click":
await clickViaPlaywright({
cdpUrl,
targetId: effectiveTargetId,
ref: action.ref,
selector: action.selector,
doubleClick: action.doubleClick,
button: action.button as "left" | "right" | "middle" | undefined,
modifiers: action.modifiers as Array<
"Alt" | "Control" | "ControlOrMeta" | "Meta" | "Shift"
>,
delayMs: action.delayMs,
timeoutMs: action.timeoutMs,
...navigationPolicy,
signal,View on GitHub (pinned to 01804a7531)
Solutions
- Flatten the batch tree so no nested-batch chain exceeds 5 levels (prefer a single-level list of actions).
- Run requests through the agent.act normalize path so the friendlier error fires earlier and the payload is flattened.
- Split the work into multiple sequential top-level batch calls instead of one deeply-nested batch.
Example fix
// before: nested batches 6 deep
{ kind: 'batch', actions: [
{ kind: 'batch', actions: [ /* ...depth 6... */ ] } ] };
// after: flatten into one level
{ kind: 'batch', actions: [ clickA, clickB, fillC /* ... */ ] }; Defensive patterns
Strategy: validation
Validate before calling
import { ACT_MAX_BATCH_DEPTH } from "./act-policy.js";
function maxBatchDepth(action, depth = 0) {
if (action.kind !== "batch") return depth;
return Math.max(depth, ...action.actions.map((a) => maxBatchDepth(a, depth + 1)));
}
if (maxBatchDepth(request) > ACT_MAX_BATCH_DEPTH) {
throw new Error(`batch nesting exceeds maximum depth of ${ACT_MAX_BATCH_DEPTH}; flatten the batch`);
}
await executeBatch(request); Type guard
function isBatchAction(a): a is { kind: 'batch'; actions: any[] } {
return a && a.kind === 'batch' && Array.isArray(a.actions);
} Try / catch
try {
await executeBatch(request);
} catch (err) {
if (err.message.startsWith('Batch nesting depth exceeds maximum')) {
// flatten nested batches into a single-level list and retry
const flat = flattenBatch(request);
await executeBatch({ kind: 'batch', actions: flat });
return;
}
throw err;
} Prevention
- Keep batch trees single-level whenever possible.
- Route requests through the agent.act normalize path so the friendlier pre-check fires first.
- When building batches programmatically, flatten nested 'batch' children into the parent's action list.
When it happens
Trigger: Submitting a batch action whose nested 'batch' children form a tree deeper than 5 levels; programmatically generated nested batches; a batch built client-side that skipped the normalize path.
Common situations: Loop that wraps results in successive batch wrappers; recursive test fixture; payload assembled from nested templates without flattening.
Related errors
- url is required
- Invalid URL: ${diagnostic}
- output path is required
- invalid profile name: use lowercase letters, numbers, and hy
- profile "${name}" already exists
AI-assisted analysis of openclaw/openclaw@01804a7531 (2026-08-12).
Data as JSON: /api/errors/3cbfb89d3722e31d.
Report an issue: GitHub.