n8n-io/n8n · error · Error

Subnode input connections are managed by parent node Subnode

Error message

Subnode input connections are managed by parent node SubnodeConfig

What it means

Thrown by SubnodeInstanceImpl.input() — subnodes (e.g. tools attached to an AI Agent) cannot declare their own input connections. Their parent SubnodeConfig node owns the connection graph, so calling .input() on the subnode itself is forbidden. The method exists only to satisfy the NodeInstance interface contract.

Source

Thrown at packages/@n8n/workflow-sdk/src/workflow-builder/node-builders/subnode-builders.ts:131

	update(config: Partial<NodeConfig>): SubnodeInstanceImpl<TType, TVersion, TOutput, TSubnodeType> {
		const mergedConfig = {
			...this.config,
			...config,
			parameters: config.parameters ?? this.config.parameters,
			credentials: config.credentials ?? this.config.credentials,
		};
		return new SubnodeInstanceImpl(
			this.type,
			this.version,
			mergedConfig,
			this._subnodeType,
			this.id,
			this.name,
		);
	}

	input(_index: number): InputTarget {
		throw new Error('Subnode input connections are managed by parent node SubnodeConfig');
	}

	output(_index: number): OutputSelector<TType, TVersion, TOutput> {
		throw new Error('Subnode output connections are managed by parent node SubnodeConfig');
	}

	then<T extends NodeInstance<string, string, unknown>>(
		_target: T | T[] | InputTarget,
		_outputIndex?: number,
	): NodeChain<NodeInstance<TType, TVersion, TOutput>, T> {
		throw new Error('Subnode connections are managed by parent node SubnodeConfig');
	}

	to<T extends NodeInstance<string, string, unknown>>(
		_target: T | T[] | InputTarget,
		_outputIndex?: number,
	): NodeChain<NodeInstance<TType, TVersion, TOutput>, T> {
		throw new Error('Subnode connections are managed by parent node SubnodeConfig');

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Do not call .input() on a subnode — read inputs from its parent SubnodeConfig node instead.
  2. Guard with a type check: if the node is a SubnodeInstance, skip the .input() call.
  3. Restructure so subnodes are only inspected via the parent's .getConnections() / subnode aggregation API.

Example fix

// before
for (const n of allNodes) {
  const target = n.input(0); // throws for subnodes
}
// after
for (const n of allNodes) {
  if (n instanceof SubnodeInstanceImpl) continue;
  const target = n.input(0);
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Before walking nodes, check whether the node is a subnode
import { SubnodeInstanceImpl } from '@n8n/workflow-sdk/workflow-builder';

if (!(node instanceof SubnodeInstanceImpl)) {
  const target = node.input(0);
}

Type guard

function isSubnodeInstance(n: unknown): n is SubnodeInstanceImpl {
  return n instanceof SubnodeInstanceImpl;
}

Prevention

When it happens

Trigger: Calling myTool.input(0) on an instance returned by a subnode builder (e.g. tool() inside an agent's tools array), or any generic code that iterates NodeInstance objects and unconditionally reads .input().

Common situations: Copying a node-walking utility that assumes every NodeInstance exposes input/output targets; writing a helper that renders connection diagrams over all nodes including subnodes.

Related errors


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