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
- Reduce the number of required parameters or consolidate them so the single-parameter lenient path applies.
- Improve the tool's description to emphasize 'valid stringified JSON object with these properties'.
- Switch to a stronger model or use the structured-tool (DynamicStructuredTool) schema path so the agent framework enforces JSON.
- 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
- Keep tool parameter count low or use a structured-tool schema.
- Re-prompt the model with the parse error so it can self-correct.
- Include an explicit 'must be valid JSON' clause in the tool description.
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
- Parameter ${parameter.name} is not a valid JSON: ${error.mes
- The response type must be an object or an array of objects
- Model did not provide parameter '${parameter.name}' which is
- Could not replace placeholders in ${key}: ${error.message}
- The type ${genericType} is not supported
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/010796171fb3d966.
Report an issue: GitHub.