n8n-io/n8n · error · NodeOperationError

At least one category must be defined

Error message

At least one category must be defined

What it means

Thrown by the Text Classifier node when the 'categories.categories' fixedCollection is empty. The classifier routes items into named categories via an LLM, so with zero categories defined there is nothing to classify against.

Source

Thrown at packages/@n8n/nodes-langchain/nodes/chains/TextClassifier/TextClassifier.node.ts:200

		const batchSize = this.getNodeParameter('options.batching.batchSize', 0, 5) as number;
		const delayBetweenBatches = this.getNodeParameter(
			'options.batching.delayBetweenBatches',
			0,
			0,
		) as number;

		const llm = (await this.getInputConnectionData(
			NodeConnectionTypes.AiLanguageModel,
			0,
		)) as BaseLanguageModel;

		const categories = this.getNodeParameter('categories.categories', 0, []) as Array<{
			category: string;
			description: string;
		}>;

		if (categories.length === 0) {
			throw new NodeOperationError(this.getNode(), 'At least one category must be defined');
		}

		const options = this.getNodeParameter('options', 0, {}) as {
			multiClass: boolean;
			fallback?: string;
			systemPromptTemplate?: string;
			enableAutoFixing: boolean;
		};
		const multiClass = options?.multiClass ?? false;
		const fallback = options?.fallback ?? 'discard';

		const schemaEntries = categories.map((cat) => [
			cat.category,
			z
				.boolean()
				.describe(
					`Should be true if the input has category "${cat.category}" (description: ${cat.description})`,
				),

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Add at least one category row (with a name and description) under the Text Classifier's Categories setting.
  2. If you want a catch-all, also configure the fallback 'other' option.
  3. Re-import the workflow from a known-good export if categories were lost.

Example fix

// before
if (categories.length === 0) {
  throw new NodeOperationError(this.getNode(), 'At least one category must be defined');
}

// after — instruct the user how to fix
if (categories.length === 0) {
  throw new NodeOperationError(this.getNode(), {
    message: 'At least one category must be defined.',
    description: 'Add category rows under Categories, each with a name and description.',
  });
}
Defensive patterns

Strategy: validation

Validate before calling

const categories = this.getNodeParameter('categories.categories', 0, []) as Array<{ category: string; description: string }>;
if (categories.length === 0) {
  throw new Error('Add at least one category row with a name and description');
}

Type guard

function hasCategories(c: unknown[]): c is Array<{ category: string; description: string }> {
  return Array.isArray(c) && c.length > 0 && c.every((x) => typeof x.category === 'string');
}

Prevention

When it happens

Trigger: User added no category rows to the Text Classifier's 'Categories' fixedCollection. The categories array length is 0 and the guard throws before any LLM call.

Common situations: User forgot to add categories; categories were cleared; workflow imported with the categories fixedCollection empty; user expected defaults but none exist for this node.

Related errors


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