n8n-io/n8n · error · NodeOperationError

error?.description || error?.message

Error message

error?.description || error?.message

What it means

This is the dynamic description of a NodeOperationError thrown by the Guardrails process handler when an 'unexpectedError' guardrail result occurs and continueOnFail is false. The thrown error's message is the underlying reason/originalException object, and its description falls back to error?.description then error?.message. It surfaces a guardrail that rejected or reported executionFailed for a reason other than a normal tripwire.

Source

Thrown at packages/@n8n/nodes-langchain/nodes/Guardrails/actions/process.ts:70

	const handleFailedResults = (results: GroupedGuardrailResults): GuardrailUserResult[] => {
		const unexpectedError = results.failed.find(
			(result) =>
				result.status === 'rejected' ||
				(result.status === 'fulfilled' && result.value.executionFailed),
		);

		if (results.failed.length && operation === 'sanitize') {
			throw new NodeOperationError(this.getNode(), 'Failed to sanitize text', {
				description: mapGuardrailErrorsToMessage(results.failed),
				itemIndex,
			});
		}
		if (unexpectedError && !this.continueOnFail()) {
			const error =
				unexpectedError.status === 'rejected'
					? unexpectedError.reason
					: unexpectedError.value.originalException;
			throw new NodeOperationError(this.getNode(), error, {
				description: error?.description || error?.message,
				itemIndex,
			});
		}
		return results.failed.map(mapGuardrailResultToUserResult);
	};

	const stageGuardrails: StageGuardRails = {
		preflight: [],
		input: [],
	};

	const checkModelAvailable = (model: BaseChatModel | null): model is BaseChatModel => {
		if (!model) {
			throw new NodeOperationError(this.getNode(), 'Chat Model is required');
		}
		return true;
	};

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Read the underlying error.message/description to identify whether it is a model/auth/network failure versus a guardrail logic failure.
  2. For transient model/API errors, retry the execution or fix credentials/connection for the upstream model.
  3. If the specific guardrail is non-essential, disable it or move it to a stage that tolerates failure.
  4. Enable 'Continue On Fail' on the node to let the workflow proceed and capture the failed item instead of aborting.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await runGuardrails(...);
} catch (e) {
  if (e instanceof NodeOperationError && e.description) {
    // log description, decide retry vs fallback
  }
}

Prevention

When it happens

Trigger: handleFailedResults() finds the first result with status === 'rejected' OR (fulfilled with value.executionFailed). With continueOnFail() false, it extracts the reason (rejected) or originalException (fulfilled) and throws NodeOperationError(node, error, { description }). Fires when a guardrail check promise rejects (network/model/runtime failure) or when a guardrail explicitly marks executionFailed.

Common situations: An LLM-backed guardrail whose model request fails (rate limit, bad credentials, timeout); a guardrail throwing on unexpected input shape; a guardrail dependency error; transient API errors surfacing through the guardrail runtime.

Related errors


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