n8n-io/n8n · error · NodeNotFoundError

NODES_NOT_FOUND

NODES_NOT_FOUND

Error message

Node with ID "${nodeId}" not found in workflow

What it means

Thrown by remove_connection when validateNodeExists returns null for sourceNodeId and/or targetNodeId. The error includes foundSource and foundTarget booleans so the caller can tell which side is missing. Code is NODES_NOT_FOUND (plural) to distinguish from the single-node NODE_NOT_FOUND factory.

Source

Thrown at packages/@n8n/ai-workflow-builder.ee/src/tools/remove-connection.tool.ts:107

				const state = getWorkflowState();
				const workflow = getCurrentWorkflow(state);

				// Report progress
				reportProgress(reporter, 'Finding nodes to disconnect...');

				// Find source and target nodes
				const sourceNode = validateNodeExists(validatedInput.sourceNodeId, workflow.nodes);
				const targetNode = validateNodeExists(validatedInput.targetNodeId, workflow.nodes);

				// Check if both nodes exist
				if (!sourceNode || !targetNode) {
					const missingNodeId = !sourceNode
						? validatedInput.sourceNodeId
						: validatedInput.targetNodeId;
					const nodeError = new NodeNotFoundError(missingNodeId);
					const error = {
						message: nodeError.message,
						code: 'NODES_NOT_FOUND',
						details: {
							sourceNodeId: validatedInput.sourceNodeId,
							targetNodeId: validatedInput.targetNodeId,
							foundSource: !!sourceNode,
							foundTarget: !!targetNode,
						},
					};
					reporter.error(error);
					return createErrorResponse(config, error);
				}

				logger?.debug('\n=== Remove Connection Tool ===');
				logger?.debug(
					`Attempting to remove connection: ${sourceNode.name} -> ${targetNode.name} (${validatedInput.connectionType})`,
				);

				// Report progress
				reportProgress(

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Inspect details.foundSource and details.foundTarget to identify the missing side.
  2. Resolve current IDs via list_nodes.
  3. Re-issue remove_connection with valid IDs.
Defensive patterns

Strategy: validation

Validate before calling

import { validateNodeExists } from '@/tools/helpers/validation';

const src = validateNodeExists(input.sourceNodeId, workflow.nodes);
const tgt = validateNodeExists(input.targetNodeId, workflow.nodes);
if (!src || !tgt) { /* surface which side is missing, refresh IDs */ }

Type guard

function isToolError(v: unknown): v is { message: string; code: string; details?: { foundSource?: boolean; foundTarget?: boolean } } {
  return typeof v === 'object' && v !== null && 'code' in v && (v as any).code === 'NODES_NOT_FOUND';
}

Try / catch

const res = await remove_connection.invoke(input);
if (isToolError(res) && res.code === 'NODES_NOT_FOUND') {
  if (!res.details?.foundSource) { /* re-resolve source */ }
  if (!res.details?.foundTarget) { /* re-resolve target */ }
}

Prevention

When it happens

Trigger: remove_connection invoked with a sourceNodeId or targetNodeId that does not match any node.id in workflow.nodes.

Common situations: Node was deleted between connect and disconnect; stale UUID; wrong workflow; ID typo.

Related errors


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