n8n-io/n8n · warning · ConnectionError

SELF_CONNECTION

SELF_CONNECTION

Error message

Cannot connect a node to itself

What it means

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.

Source

Thrown at packages/@n8n/ai-workflow-builder.ee/src/tools/helpers/validation.ts:68

				nt.name === nodeTypeName &&
				(Array.isArray(nt.version) ? nt.version.includes(nodeVersion) : nt.version === nodeVersion),
		) ?? null
	);
}

/**
 * Validate that a connection is possible between two nodes
 */
export function validateConnection(sourceNode: INode, targetNode: INode): ToolError | null {
	// Check if source and target are the same
	if (sourceNode.id === targetNode.id) {
		const error = new ConnectionError('Cannot connect a node to itself', {
			fromNodeId: sourceNode.id,
			toNodeId: targetNode.id,
		});
		return {
			message: error.message,
			code: 'SELF_CONNECTION',
			details: { sourceId: sourceNode.id, targetId: targetNode.id },
		};
	}

	return null;
}

/**
 * Create a validation error
 */
export function createValidationError(
	message: string,
	code: string,
	details?: Record<string, string>,
): ToolError {
	// Create the appropriate error instance for better tracking
	const error = new ValidationError(message, { tags: { code, ...details } });
	return {

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Verify the two UUIDs differ before invoking.
  2. Call list_nodes to enumerate current node IDs and pick distinct source and target.
  3. If a cyclic topology is genuinely needed, route through an intermediate No-Op/Set node.

Example fix

// before
connect_nodes.invoke({ sourceNodeId: id, targetNodeId: id });
// after
connect_nodes.invoke({ sourceNodeId: sourceId, targetNodeId: distinctTargetId });
Defensive patterns

Strategy: validation

Validate before calling

// Guard before invoking connect_nodes.
if (input.sourceNodeId === input.targetNodeId) {
  // refuse or prompt the agent for a distinct target
}

Try / catch

const res = await connect_nodes.invoke(input);
if (isToolError(res) && res.code === 'SELF_CONNECTION') {
  // prompt for a distinct target node
}

Prevention

When it happens

Trigger: Calling connect_nodes (or any consumer of validateConnection) with identical sourceNodeId and targetNodeId UUIDs.

Common situations: The LLM passes the same UUID twice (copy-paste); a duplicated-variable bug in agent code; an attempt to create a self-loop.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/6aa94001a0c5eb75. Report an issue: GitHub.