{"record":{"id":"3cbfb89d3722e31d","repo":"openclaw/openclaw","slug":"batch-nesting-depth-exceeds-maximum-of-act-max-b","errorCode":null,"errorMessage":"Batch nesting depth exceeds maximum of ${ACT_MAX_BATCH_DEPTH}","messagePattern":"Batch nesting depth exceeds maximum of (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"extensions/browser/src/browser/pw-tools-core.interactions.execution.ts","lineNumber":56,"sourceCode":"  type GuardedInteractionOptions,\n  hasInteractionNavigationPolicy,\n  interactionNavigationPolicy,\n} from \"./pw-tools-core.interactions.navigation.js\";\nimport { closePageViaPlaywright, resizeViewportViaPlaywright } from \"./pw-tools-core.snapshot.js\";\n\nconst ACT_DOWNLOAD_MAX_DRAIN_MS = 1_000;\n\nasync function executeSingleAction(\n  action: BrowserActRequest,\n  cdpUrl: string,\n  targetId?: string,\n  evaluateEnabled?: boolean,\n  navigationPolicy: BrowserNavigationPolicyOptions = {},\n  depth = 0,\n  signal?: AbortSignal,\n): Promise<unknown> {\n  if (depth > ACT_MAX_BATCH_DEPTH) {\n    throw new Error(`Batch nesting depth exceeds maximum of ${ACT_MAX_BATCH_DEPTH}`);\n  }\n  const effectiveTargetId = action.targetId ?? targetId;\n  switch (action.kind) {\n    case \"click\":\n      await clickViaPlaywright({\n        cdpUrl,\n        targetId: effectiveTargetId,\n        ref: action.ref,\n        selector: action.selector,\n        doubleClick: action.doubleClick,\n        button: action.button as \"left\" | \"right\" | \"middle\" | undefined,\n        modifiers: action.modifiers as Array<\n          \"Alt\" | \"Control\" | \"ControlOrMeta\" | \"Meta\" | \"Shift\"\n        >,\n        delayMs: action.delayMs,\n        timeoutMs: action.timeoutMs,\n        ...navigationPolicy,\n        signal,","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/openclaw/openclaw/blob/01804a75319da4b69c9ab98ceaa30477e22b8c0b/extensions/browser/src/browser/pw-tools-core.interactions.execution.ts#L38-L74","documentation":"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.","triggerScenarios":"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.","commonSituations":"Loop that wraps results in successive batch wrappers; recursive test fixture; payload assembled from nested templates without flattening.","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."],"exampleFix":"// before: nested batches 6 deep\n{ kind: 'batch', actions: [\n  { kind: 'batch', actions: [ /* ...depth 6... */ ] } ] };\n\n// after: flatten into one level\n{ kind: 'batch', actions: [ clickA, clickB, fillC /* ... */ ] };","handlingStrategy":"validation","validationCode":"import { ACT_MAX_BATCH_DEPTH } from \"./act-policy.js\";\n\nfunction maxBatchDepth(action, depth = 0) {\n  if (action.kind !== \"batch\") return depth;\n  return Math.max(depth, ...action.actions.map((a) => maxBatchDepth(a, depth + 1)));\n}\nif (maxBatchDepth(request) > ACT_MAX_BATCH_DEPTH) {\n  throw new Error(`batch nesting exceeds maximum depth of ${ACT_MAX_BATCH_DEPTH}; flatten the batch`);\n}\nawait executeBatch(request);","typeGuard":"function isBatchAction(a): a is { kind: 'batch'; actions: any[] } {\n  return a && a.kind === 'batch' && Array.isArray(a.actions);\n}","tryCatchPattern":"try {\n  await executeBatch(request);\n} catch (err) {\n  if (err.message.startsWith('Batch nesting depth exceeds maximum')) {\n    // flatten nested batches into a single-level list and retry\n    const flat = flattenBatch(request);\n    await executeBatch({ kind: 'batch', actions: flat });\n    return;\n  }\n  throw err;\n}","preventionTips":["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."],"tags":["browser","batch","depth-limit","validation","recursion"],"backgroundTag":null,"analyzedSha":"01804a75319da4b69c9ab98ceaa30477e22b8c0b","analyzedAt":"2026-08-12T04:37:58.197Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}