n8n-io/n8n · error · NodeOperationError

A non-empty prompt is required.

Error message

A non-empty prompt is required.

What it means

The Text Message operation requires at least one message with non-empty content. After reading the messages array from the parameter, the code checks that at least one message has content that is a non-empty trimmed string. If all messages are empty or contain only whitespace, it throws a NodeOperationError before calling the API.

Source

Thrown at packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/v1/actions/text/message.operation.ts:245

		],
	},
];

const displayOptions = {
	show: {
		operation: ['message'],
		resource: ['text'],
	},
};

export const description = updateDisplayOptions(displayOptions, properties);

export async function execute(this: IExecuteFunctions, i: number): Promise<INodeExecutionData[]> {
	const nodeVersion = this.getNode().typeVersion;
	const model = this.getNodeParameter('modelId', i, '', { extractValue: true });
	let messages = this.getNodeParameter('messages.values', i, []) as IDataObject[];
	if (!messages.some((m) => typeof m.content === 'string' && m.content.trim() !== '')) {
		throw new NodeOperationError(this.getNode(), 'A non-empty prompt is required.', {
			itemIndex: i,
		});
	}
	const options = this.getNodeParameter('options', i, {});
	const jsonOutput = this.getNodeParameter('jsonOutput', i, false) as boolean;
	const maxToolsIterations =
		nodeVersion >= 1.5 ? (this.getNodeParameter('options.maxToolsIterations', i, 15) as number) : 0;

	const abortSignal = this.getExecutionCancelSignal();

	if (options.maxTokens !== undefined) {
		options.max_completion_tokens = options.maxTokens;
		delete options.maxTokens;
	}

	if (options.topP !== undefined) {
		options.top_p = options.topP;
		delete options.topP;

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Ensure at least one message in the messages array has non-empty content text
  2. If messages come from upstream, use an IF node to filter out items with empty message content
  3. Add a fallback expression: {{$json["content"] || 'Hello'}}
  4. Verify the messages.values path is correctly mapped from the upstream data

Example fix

// before — messages: [{ role: 'user', content: '' }]
// after  — messages: [{ role: 'user', content: 'Summarize the following text' }]
Defensive patterns

Strategy: validation

Validate before calling

const messages = this.getNodeParameter('messages.values', i, []) as IDataObject[];
const hasNonEmptyContent = messages.some(
  (m) => typeof m.content === 'string' && m.content.trim() !== ''
);
if (!hasNonEmptyContent) {
  throw new UserError('At least one message must have non-empty content.');
}

Type guard

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

Prevention

When it happens

Trigger: The messages.values array contains only messages with empty or whitespace-only content strings. The check uses .some() to verify at least one message has content that is a string and .trim() is non-empty. If none pass, the error fires.

Common situations: Messages are populated from upstream expressions that resolve to empty; a template/fixedCollection message was added but its text field was left blank; a previous Set node cleared the content field.

Related errors


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