n8n-io/n8n · error · NodeOperationError

Input is not a valid JSON: ${error.message}

Error message

Input is not a valid JSON: ${error.message}

What it means

Thrown by configureToolFunction in the AI HTTP Request tool when the model's query string fails to parse as JSON AND the tool defines more than one parameter. With exactly one parameter the tool is lenient and wraps the raw string, but with multiple parameters it cannot guess the mapping and aborts.

Source

Thrown at packages/@n8n/nodes-langchain/nodes/tools/ToolHttpRequest/utils.ts:735

		let response: string = '';
		let executionError: Error | undefined = undefined;

		if (!toolParameters.length) {
			query = '{}';
		}

		try {
			if (query) {
				let dataFromModel;

				if (typeof query === 'string') {
					try {
						dataFromModel = jsonParse<IDataObject>(query);
					} catch (error) {
						if (toolParameters.length === 1) {
							dataFromModel = { [toolParameters[0].name]: query };
						} else {
							throw new NodeOperationError(
								ctx.getNode(),
								`Input is not a valid JSON: ${error.message}`,
								{ itemIndex },
							);
						}
					}
				} else {
					dataFromModel = query;
				}

				for (const parameter of toolParameters) {
					if (
						parameter.required &&
						(dataFromModel[parameter.name] === undefined || dataFromModel[parameter.name] === null)
					) {
						throw new NodeOperationError(
							ctx.getNode(),
							`Model did not provide parameter '${parameter.name}' which is required and must be present in the input`,

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Reduce the number of required parameters or consolidate them so the single-parameter lenient path applies.
  2. Improve the tool's description to emphasize 'valid stringified JSON object with these properties'.
  3. Switch to a stronger model or use the structured-tool (DynamicStructuredTool) schema path so the agent framework enforces JSON.
  4. Pre-validate the model output and re-prompt on malformed JSON.

Example fix

// before: model returns 'search tomatoes' for a 2-param tool → throws
// after: enforce schema with a structured tool so the framework serializes args
// (use the node's 'Specify Input Schema' option, or reduce to one parameter)

// defensive parse in custom code:
let data;
try { data = JSON.parse(query); }
catch { data = { param1: query }; /* single-param fallback */ }
Defensive patterns

Strategy: try-catch

Validate before calling

let dataFromModel: IDataObject;
if (typeof query === 'string') {
  try { dataFromModel = JSON.parse(query); }
  catch {
    if (toolParameters.length === 1) dataFromModel = { [toolParameters[0].name]: query };
    else throw new Error('Provide a valid JSON object with all parameters');
  }
} else dataFromModel = query as IDataObject;

Type guard

function isParsableJson(s: string): boolean {
  try { JSON.parse(s); return true; } catch { return false; }
}

Try / catch

try { dataFromModel = jsonParse<IDataObject>(query); }
catch (e) { /* single-param fallback or re-prompt the model */ }

Prevention

When it happens

Trigger: An LLM returns plain text or malformed JSON (unquoted keys, trailing commas, single quotes) as the tool call argument when the tool schema declares 2+ parameters; the model ignores the 'stringified JSON object' instruction in the tool description.

Common situations: Weaker models that hallucinate argument formats; long parameter lists that confuse the model; prompt/description edits that drop the JSON requirement; tool calling with a non-structured-tool agent.

Related errors


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