n8n-io/n8n · error · NodeOperationError

The value in the "Extra Body" field must be a JSON object

Error message

The value in the "Extra Body" field must be a JSON object

What it means

Sibling to error 690: thrown after jsonParse succeeds but isPlainObject(extraBody) is false. OpenAI's request body expects a top-level object of key/value overrides, so a JSON array, number, string, or boolean is rejected even though it parses.

Source

Thrown at packages/@n8n/nodes-langchain/nodes/llms/LMChatOpenAi/LmChatOpenAi.node.ts:822

			if (options.responseFormat) modelKwargs.response_format = { type: options.responseFormat };
			if (options.reasoningEffort && ['low', 'medium', 'high'].includes(options.reasoningEffort)) {
				modelKwargs.reasoning_effort = options.reasoningEffort;
			}
		}

		if (options.extraBody) {
			let extraBody: Record<string, unknown>;
			try {
				extraBody = jsonParse<Record<string, unknown>>(options.extraBody);
			} catch (error) {
				throw new NodeOperationError(
					this.getNode(),
					'The value in the "Extra Body" field is not valid JSON',
					{ itemIndex, description: error instanceof Error ? error.message : String(error) },
				);
			}
			if (!isPlainObject(extraBody)) {
				throw new NodeOperationError(
					this.getNode(),
					'The value in the "Extra Body" field must be a JSON object',
					{ itemIndex },
				);
			}
			Object.assign(modelKwargs, extraBody);
		}

		const includedOptions = pick(options, [
			'frequencyPenalty',
			'maxTokens',
			'presencePenalty',
			'temperature',
			'topP',
			'baseURL',
		]);

		const fields: ChatOpenAIFields = {

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Wrap the value in an object: {"key": value}.
  2. Find the correct OpenAI parameter name for the intended override and use it as the object key.
  3. Clear the field when no overrides are needed.

Example fix

// before
options.extraBody = "[\"a\", \"b\"]"
// after
options.extraBody = "{\"stop\": [\"a\", \"b\"]}"
Defensive patterns

Strategy: type-guard

Validate before calling

if (options.extraBody) {
  const v = JSON.parse(options.extraBody);
  if (typeof v !== 'object' || v === null || Array.isArray(v)) {
    throw new Error("'Extra Body' must be a JSON object");
  }
}

Type guard

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

Try / catch

// Validate shape after parsing; reject non-objects before submission.

Prevention

When it happens

Trigger: User enters a JSON array, primitive, or string in 'Extra Body' — e.g. ["a","b"], 0.5, true, or "hello". Each parses cleanly but isPlainObject returns false.

Common situations: Confusing extraBody with a list option; pasting a bare value; templating that emits an array literal; misunderstanding the field's purpose.

Related errors


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