n8n-io/n8n · error · NodeOperationError

Documents must be an array

Error message

Documents must be an array

What it means

validateEmbedDocumentsInput() guards embedDocuments(): documents must be an array. Because the embed call iterates the array, a non-array (string, object, undefined) would either mis-embed or crash deeper, so it fails fast with a NodeOperationError pointing at the expected shape (array of strings).

Source

Thrown at packages/@n8n/ai-utilities/src/utils/embeddings-input-validation.ts:34

			description:
				'The text provided for embedding is empty or undefined. This can happen when: the input expression evaluates to undefined, the AI agent calls a tool without proper arguments, or a required field is missing.',
		});
	}
	return query;
}

/**
 * Validates documents input for embedDocuments operations.
 * Throws NodeOperationError if documents array is invalid or contains invalid entries.
 *
 * @param documents - The documents array to validate
 * @param node - The node for error context
 * @returns The validated documents array
 * @throws NodeOperationError if documents is not an array or contains invalid entries
 */
export function validateEmbedDocumentsInput(documents: unknown, node: INode): string[] {
	if (!Array.isArray(documents)) {
		throw new NodeOperationError(node, 'Documents must be an array', {
			description: 'Expected an array of strings to embed.',
		});
	}

	const invalidIndex = documents.findIndex(
		(doc) => doc === undefined || doc === null || doc === '',
	);

	if (invalidIndex !== -1) {
		throw new NodeOperationError(node, `Invalid document at index ${invalidIndex}`, {
			description: `Document at index ${invalidIndex} is empty or undefined. All documents must be non-empty strings.`,
		});
	}

	return documents;
}

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Provide an array of strings: wrap a single value with `[$json.text]` or use an aggregate node.
  2. Validate before the embedding node: `if (!Array.isArray(docs)) ...`.
  3. Check the upstream node's output type and adjust the mapping.

Example fix

// before
await embedDocuments($json.singleText, ...);

// after
await embedDocuments([$json.singleText], ...);
Defensive patterns

Strategy: validation

Validate before calling

import { validateEmbedDocumentsInput } from '@n8n/ai-utilities';
// or inline:
function isStringArray(v: unknown): v is string[] {
  return Array.isArray(v) && v.every((x) => typeof x === 'string');
}
if (!isStringArray(docs)) {
  throw new Error('documents must be an array of strings');
}

Type guard

function isStringArray(v: unknown): v is string[] {
  return Array.isArray(v) && v.every((x) => typeof x === 'string');
}

Prevention

When it happens

Trigger: The documents input is a single string instead of an array; an object; undefined because the source expression resolved to nothing; a previous node emitted a single item where an array of items was expected.

Common situations: Mapping `$json.text` (a string) instead of `$json.lines` (array) into the documents input; a Split-In-Batches/aggregate mismatch; an expression returning undefined; a tool returning a single doc instead of a list.

Related errors


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