{"record":{"id":"a719a77053c3a642","repo":"n8n-io/n8n","slug":"workflow-generation-stopped-the-ai-reached-the-ma","errorCode":null,"errorMessage":"Workflow generation stopped: The AI reached the maximum number of steps while building your workflow. This usually means the workflow design became too complex or got stuck in a loop while trying to create the nodes and connections.","messagePattern":"Workflow generation stopped: The AI reached the maximum number of steps while building your workflow\\. This usually means the workflow design became too complex or got stuck in a loop while trying to create the nodes and connections\\.","errorType":"exception","errorClass":"UserError","httpStatus":null,"severity":"warning","filePath":"packages/@n8n/ai-workflow-builder.ee/src/workflow-builder-agent.ts","lineNumber":648,"sourceCode":"\t\t) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\tconst messages = (await agent.getState(threadConfig)).values.messages as Array<\n\t\t\t\tAIMessage | HumanMessage | ToolMessage\n\t\t\t>;\n\n\t\t\t// Handle abort errors gracefully\n\t\t\tconst abortedAiMessage = new AIMessage({\n\t\t\t\tcontent: 'Task aborted',\n\t\t\t\tid: crypto.randomUUID(),\n\t\t\t});\n\t\t\t// TODO: Should we clear tool calls that are in progress?\n\t\t\tawait agent.updateState(threadConfig, { messages: [...messages, abortedAiMessage] });\n\t\t\treturn;\n\t\t}\n\n\t\t// If it's not an abort error, check for GraphRecursionError\n\t\tif (error instanceof GraphRecursionError) {\n\t\t\tthrow new UserError(WORKFLOW_TOO_COMPLEX_ERROR);\n\t\t}\n\n\t\t// Check for 401 expired token errors (typically from long-running generations)\n\t\tif (this.isTokenExpiredError(error)) {\n\t\t\tthrow new UserError(WORKFLOW_TOO_COMPLEX_ERROR);\n\t\t}\n\n\t\t// Re-throw any other errors\n\t\tthrow error;\n\t}\n\n\t/**\n\t * Checks if the error is a 401 expired token error from the LLM provider proxy.\n\t * This typically occurs during very long-running workflow generations when\n\t * the AI assistant service proxy token expires.\n\t *\n\t * We specifically check for LangChain's MODEL_AUTHENTICATION error code to ensure\n\t * we only catch authentication errors from the LLM provider, not unrelated 401s.","sourceCodeStart":630,"sourceCodeEnd":666,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/ai-workflow-builder.ee/src/workflow-builder-agent.ts#L630-L666","documentation":"UserError thrown in handleAgentStreamError when the caught error is a LangGraph GraphRecursionError. The recursion limit is MAX_MULTI_AGENT_STREAM_ITERATIONS (set on streamConfig.recursionLimit in setupAgentAndConfigs). Hitting it means the multi-agent graph looped more times than allowed without producing a terminal state. The fixed WORKFLOW_TOO_COMPLEX_ERROR message is surfaced to the user.","triggerScenarios":"processAgentStream catches a GraphRecursionError from agent.stream. This happens when the supervisor/builder subgraphs keep handing control back and forth (or a tool keeps returning retryable results) until the recursion budget is exhausted.","commonSituations":"An ambiguous prompt makes the planner repeatedly revise; a node-creation tool fails in a way the agent retries indefinitely; a complex target workflow needs more steps than the configured ceiling; a model regression causes tool-call looping.","solutions":["Rephrase the request more specifically so the agent converges faster.","Break the desired workflow into smaller build steps across multiple turns.","If legitimate workflows routinely hit the cap, raise MAX_MULTI_AGENT_STREAM_ITERATIONS after reviewing cost/latency.","Check logs for repeated tool calls indicating a stuck loop and report if it persists."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Hint at complexity up front — heuristic\nconst nodeCount = workflowContext?.currentWorkflow?.nodes?.length ?? 0;\nif (nodeCount > 80) {\n  // warn the user the request may exceed the agent's step budget\n}","typeGuard":"import { GraphRecursionError } from '@langchain/langgraph';\nconst isRecursionError = (e: unknown): boolean => e instanceof GraphRecursionError;","tryCatchPattern":"try {\n  yield* builder.chat(payload);\n} catch (e) {\n  if (e instanceof UserError && /maximum number of steps/.test(e.message)) {\n    // rephrase request into smaller steps and retry incrementally\n  }\n  throw e;\n}","preventionTips":["Prefer many small, specific requests over one large ambiguous request.","Monitor agent traces for repeated tool calls that signal a loop.","Tune MAX_MULTI_AGENT_STREAM_ITERATIONS only after cost analysis."],"tags":["ai-workflow-builder","langgraph","recursion-limit","agent-loop"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}