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
- Create the node with type 'n8n-nodes-base.switch' before calling .onCase().
- For IF nodes use .onTrue()/.onFalse(); for plain fan-out use .to().
- 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
- Create Switch nodes explicitly with node('n8n-nodes-base.switch', ...).
- Narrow with isSwitchNodeType before calling .onCase().
- Reserve .onCase() for Switch nodes; use .onTrue()/.onFalse() for IF and .to() for plain fan-out.
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
- .onTrue() is only available on IF nodes (${NODE_TYPES.IF})
- .onFalse() is only available on IF nodes (${NODE_TYPES.IF})
- SDK_REPEATED_BRANCH_WIRING
- SplitInBatches node input connections are managed by SplitIn
- SplitInBatches node output connections are managed by SplitI
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/cf34a7a9b535e964.
Report an issue: GitHub.