n8n-io/n8n · error · Error

.onCase() is only available on Switch nodes (${NODE_TYPES.SW

Error message

.onCase() is only available on Switch nodes (${NODE_TYPES.SWITCH})

What it means

Thrown by NodeInstanceImpl.onCase() when isSwitchNodeType(this.type) returns false. The .onCase(index, target) branch builder targets a specific case output index that only exists on n8n-nodes-base.switch nodes; calling it on any other node type is rejected.

Source

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

		if (!isIfNodeType(this.type)) {
			throw new Error(`.onFalse() is only available on IF nodes (${NODE_TYPES.IF})`);
		}
		const builder = new IfElseBuilderImpl<TOutput>(
			this as unknown as NodeInstance<'n8n-nodes-base.if', string, TOutput>,
		);
		return builder.onFalse(target);
	}

	/**
	 * Start building a Switch case with a case target.
	 * Only available on Switch nodes (n8n-nodes-base.switch).
	 *
	 * @example
	 * switchNode.onCase(0, caseA).onCase(1, caseB)
	 */
	onCase(index: number, target: SwitchCaseTarget): SwitchCaseBuilder<TOutput> {
		if (!isSwitchNodeType(this.type)) {
			throw new Error(`.onCase() is only available on Switch nodes (${NODE_TYPES.SWITCH})`);
		}
		const builder = new SwitchCaseBuilderImpl<TOutput>(
			this as unknown as NodeInstance<'n8n-nodes-base.switch', string, TOutput>,
		);
		return builder.onCase(index, target);
	}

	onError<T extends NodeInstance<string, string, unknown>>(handler: T | InputTarget): this {
		// Declaring an error route implies the error output port exists.
		this.config.onError ??= 'continueErrorOutput';
		if (isInputTarget(handler)) {
			this._connections.push({
				target: handler.node,
				outputIndex: 0,
				targetInputIndex: handler.inputIndex,
				connectionType: 'error',
			});
		} else {

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Create the node with type 'n8n-nodes-base.switch' before calling .onCase().
  2. For IF nodes use .onTrue()/.onFalse(); for plain fan-out use .to().
  3. Narrow with isSwitchNodeType before calling .onCase().

Example fix

// before
const n = node('n8n-nodes-base.if', 'v1', { ... });
n.onCase(0, handler); // throws
// after
const sw = node('n8n-nodes-base.switch', 'v1', { ... });
sw.onCase(0, caseA).onCase(1, caseB);
Defensive patterns

Strategy: type-guard

Validate before calling

function assertSwitchNode(node: NodeInstance): asserts node is NodeInstance<'n8n-nodes-base.switch', string, unknown> {
  if (node.type !== 'n8n-nodes-base.switch') {
    throw new Error(`.onCase() requires a Switch node, got ${node.type}`);
  }
}

assertSwitchNode(myNode);
myNode.onCase(0, handler);

Type guard

import { isSwitchNodeType } from '@n8n/workflow-sdk';

function isSwitchNode(node: NodeInstance): node is NodeInstance<'n8n-nodes-base.switch', string, unknown> {
  return isSwitchNodeType(node.type);
}

Prevention

When it happens

Trigger: Calling someNode.onCase(0, target) where someNode is an IF, Code, HTTP, or any non-Switch node; using an IF node's output indexing to drive case wiring.

Common situations: Wrong node type selected (IF used where Switch was meant); copy-paste from a Switch example; dynamic node construction with the wrong type string.

Related errors


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