n8n-io/n8n · error · NodeOperationError

A non-empty prompt is required.

Error message

A non-empty prompt is required.

What it means

Thrown in the Gemini 'text / message' operation after the assembled messages array is filtered to those whose content.trim() !== ''. If that filter yields zero messages, there is nothing to send to generateContent, so the node refuses the request with itemIndex context.

Source

Thrown at packages/@n8n/nodes-langchain/nodes/vendors/GoogleGemini/actions/text/message.operation.ts:515

				tools.push({
					fileSearch: {
						...(fileSearchStoreNames && { fileSearchStoreNames }),
						...(metadataFilter && { metadataFilter }),
					},
				});
			}

			if (builtInTools.codeExecution) {
				tools.push({
					codeExecution: {},
				});
			}
		}
	}

	const nonEmptyMessages = messages.filter((m) => m.content.trim() !== '');
	if (!nonEmptyMessages.length) {
		throw new NodeOperationError(this.getNode(), 'A non-empty prompt is required.', {
			itemIndex: i,
		});
	}
	const contents: Content[] = nonEmptyMessages.map((m) => ({
		parts: [{ text: m.content }],
		role: m.role,
	}));
	const body: GenerateContentRequest = {
		tools,
		contents,
		generationConfig,
		systemInstruction: options.systemMessage
			? { parts: [{ text: options.systemMessage }] }
			: undefined,
		...(toolConfig && { toolConfig }),
	};

	let response = (await apiRequest.call(this, 'POST', `/v1beta/${model}:generateContent`, {

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Ensure at least one message role has non-empty content for the item — typically the 'user' message must carry text.
  2. If the content is expression-driven, preview the resolved value and fix the reference (e.g. use $json.message ?? $json.text or a fallback string).
  3. When using memory/templates, confirm the template interpolates a non-empty variable or provides default text.
  4. Filter the input upstream so items with no text don't reach this node.

Example fix

// before — content can resolve to ''
const content = $json.userInput;

// after — guarantee non-empty
const content = ($json.userInput ?? '').trim() || 'Hello';
Defensive patterns

Strategy: validation

Validate before calling

const messages = /* …built messages… */;
const nonEmpty = messages.filter((m) => m.content.trim() !== '');
if (nonEmpty.length === 0) {
  throw new Error('Refusing to call Gemini: no message has non-empty content');
}

Type guard

function hasNonEmptyMessage(messages: { content: string }[]): boolean {
  return messages.some((m) => m.content.trim() !== '');
}

Prevention

When it happens

Trigger: All chat messages resolved to empty/whitespace-only strings: a Chat Trigger with no user text, a memory/prompt template that produced blank content for every role, an expression referencing a field that is undefined for the current item, or a system message only with no user turn.

Common situations: Connected a memory node whose retrieval returned nothing and the prompt template collapsed to empty; referenced $json.missingField in the message content; the trigger payload's text field is genuinely empty for this run.

Related errors


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