{"record":{"id":"6aa94001a0c5eb75","repo":"n8n-io/n8n","slug":"self-connection","errorCode":"SELF_CONNECTION","errorMessage":"Cannot connect a node to itself","messagePattern":"Cannot connect a node to itself","errorType":"error_code","errorClass":"ConnectionError","httpStatus":null,"severity":"warning","filePath":"packages/@n8n/ai-workflow-builder.ee/src/tools/helpers/validation.ts","lineNumber":68,"sourceCode":"\t\t\t\tnt.name === nodeTypeName &&\n\t\t\t\t(Array.isArray(nt.version) ? nt.version.includes(nodeVersion) : nt.version === nodeVersion),\n\t\t) ?? null\n\t);\n}\n\n/**\n * Validate that a connection is possible between two nodes\n */\nexport function validateConnection(sourceNode: INode, targetNode: INode): ToolError | null {\n\t// Check if source and target are the same\n\tif (sourceNode.id === targetNode.id) {\n\t\tconst error = new ConnectionError('Cannot connect a node to itself', {\n\t\t\tfromNodeId: sourceNode.id,\n\t\t\ttoNodeId: targetNode.id,\n\t\t});\n\t\treturn {\n\t\t\tmessage: error.message,\n\t\t\tcode: 'SELF_CONNECTION',\n\t\t\tdetails: { sourceId: sourceNode.id, targetId: targetNode.id },\n\t\t};\n\t}\n\n\treturn null;\n}\n\n/**\n * Create a validation error\n */\nexport function createValidationError(\n\tmessage: string,\n\tcode: string,\n\tdetails?: Record<string, string>,\n): ToolError {\n\t// Create the appropriate error instance for better tracking\n\tconst error = new ValidationError(message, { tags: { code, ...details } });\n\treturn {","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/ai-workflow-builder.ee/src/tools/helpers/validation.ts#L50-L86","documentation":"validateConnection() in helpers/validation.ts returns a ToolError with code SELF_CONNECTION when sourceNode.id === targetNode.id. n8n forbids a node connecting to itself; this guard runs before any IO compatibility check.","triggerScenarios":"Calling connect_nodes (or any consumer of validateConnection) with identical sourceNodeId and targetNodeId UUIDs.","commonSituations":"The LLM passes the same UUID twice (copy-paste); a duplicated-variable bug in agent code; an attempt to create a self-loop.","solutions":["Verify the two UUIDs differ before invoking.","Call list_nodes to enumerate current node IDs and pick distinct source and target.","If a cyclic topology is genuinely needed, route through an intermediate No-Op/Set node."],"exampleFix":"// before\nconnect_nodes.invoke({ sourceNodeId: id, targetNodeId: id });\n// after\nconnect_nodes.invoke({ sourceNodeId: sourceId, targetNodeId: distinctTargetId });","handlingStrategy":"validation","validationCode":"// Guard before invoking connect_nodes.\nif (input.sourceNodeId === input.targetNodeId) {\n  // refuse or prompt the agent for a distinct target\n}","typeGuard":null,"tryCatchPattern":"const res = await connect_nodes.invoke(input);\nif (isToolError(res) && res.code === 'SELF_CONNECTION') {\n  // prompt for a distinct target node\n}","preventionTips":["Always diff sourceNodeId and targetNodeId before invoking.","Use list_nodes to source distinct IDs.","Model cycles via an intermediate node rather than self-loops."],"tags":["workflow-builder","connections","validation","guard"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}