n8n-io/n8n · error · TypeError

${fnName}() requires ${hint}, but received ${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.

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)

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.