n8n-io/n8n · error · TypeError

() requires , but received .

Error message

${fnName}() requires ${hint}, but received ${received}.

What it means

A runtime guard inside the workflow-builder SDK. assertPlainObject() rejects any value that is not a plain object: null, arrays, strings, numbers, booleans, and undefined all fail. It is called by builder helpers (e.g. node config, parameters, settings) to enforce that the caller passed a real object before the builder spreads or iterates its keys. The thrown TypeError carries the offending function name, a human hint about what was expected, and the actual received type so the caller can pinpoint the bad argument.

Solutions

  1. Inspect the received type in the error message, then fix the call site to pass a plain object (e.g. JSON.parse the string, replace null with {}, unwrap the array element).
  2. If the value legitimately may be absent, pass an explicit empty object {} or guard the call with a conditional.
  3. Add a type annotation at the call site so TypeScript catches the mismatch at compile time instead of at runtime.

Example fix

// before
workflow.add(trigger({ parameters: '{"a":1}' }));

// after
workflow.add(trigger({ parameters: JSON.parse('{"a":1}') }));
Defensive patterns

Strategy: type-guard

Validate before calling

function isPlainObject(v: unknown): v is Record<string, unknown> {
  return typeof v === 'object' && v !== null && !Array.isArray(v);
}

if (!isPlainObject(config)) {
  throw new Error('config must be a plain object');
}

Type guard

function isPlainObject(v: unknown): v is Record<string, unknown> {
  return typeof v === 'object' && v !== null && !Array.isArray(v);
}

Try / catch

try {
  assertPlainObject(params, 'trigger', 'a parameters object');
} catch (e) {
  if (e instanceof TypeError) {
    console.error('Bad parameters for trigger():', e.message);
    // fallback or rethrow
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling a builder factory or helper with a non-object argument where an object is required: passing a JSON string instead of a parsed object to a parameters/config field, passing null for an optional-but-object-typed argument, passing an array where a parameters object is expected, or passing a number/boolean from a loosely-typed caller. The check fires synchronously on the first invalid argument before any node is constructed.

Common situations: A user reads config from an env var or file as a string and forgets JSON.parse(); a caller spreads undefined into a config object and the merged value becomes undefined; a typed-as-any integration passes a primitive where the SDK expects a parameters bag; migration code that previously accepted loose input now hits the stricter guard.

Related errors


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

Appendix: source

Thrown at packages/@n8n/workflow-sdk/src/workflow-builder/validation-helpers.ts:16

/**
 * Validation helper functions for workflow builder
 * Pure functions extracted from WorkflowBuilderImpl
 */

import { isPlaceholderValue } from './string-utils';
import { isTriggerNodeType } from '../utils/trigger-detection';

/**
 * Assert that input is a plain (non-null, non-array) object.
 * Throws a descriptive TypeError when called with a string, number, null, or array.
 */
export function assertPlainObject(input: unknown, fnName: string, hint: string): void {
	if (typeof input !== 'object' || input === null || Array.isArray(input)) {
		const received = input === null ? 'null' : Array.isArray(input) ? 'an array' : typeof input;
		throw new TypeError(`${fnName}() requires ${hint}, but received ${received}.`);
	}
}

/**
 * Check if a value contains an n8n expression
 */
export function containsExpression(value: unknown): boolean {
	if (typeof value !== 'string') {
		return false;
	}
	return value.includes('={{') || value.startsWith('=');
}

/**
 * Check if a value contains a malformed expression ({{ $ without = prefix)
 */
export function containsMalformedExpression(value: unknown): boolean {
	if (typeof value !== 'string') {

View on GitHub (pinned to 5ac6606e81)