{"record":{"id":"fd9770d8b53869e1","repo":"n8n-io/n8n","slug":"the-response-type-must-be-an-object-or-an-array-of","errorCode":null,"errorMessage":"The response type must be an object or an array of objects","messagePattern":"The response type must be an object or an array of objects","errorType":"exception","errorClass":"NodeOperationError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/nodes-langchain/nodes/tools/ToolHttpRequest/utils.ts","lineNumber":399,"sourceCode":"\n\t\tif (maxLength > 0 && text.length > maxLength) {\n\t\t\treturn text.substring(0, maxLength);\n\t\t}\n\n\t\treturn text;\n\t};\n};\n\nconst jsonOptimizer = (ctx: ISupplyDataFunctions, itemIndex: number) => {\n\treturn (response: string): string => {\n\t\tlet responseData: IDataObject | IDataObject[] | string = response;\n\n\t\tif (typeof responseData === 'string') {\n\t\t\tresponseData = jsonParse(response);\n\t\t}\n\n\t\tif (typeof responseData !== 'object' || !responseData) {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tctx.getNode(),\n\t\t\t\t'The response type must be an object or an array of objects',\n\t\t\t\t{ itemIndex },\n\t\t\t);\n\t\t}\n\n\t\tconst dataField = ctx.getNodeParameter('dataField', itemIndex, '') as string;\n\t\tlet returnData: IDataObject[] = [];\n\n\t\tif (!Array.isArray(responseData)) {\n\t\t\tif (dataField) {\n\t\t\t\tconst data = responseData[dataField] as IDataObject | IDataObject[];\n\t\t\t\tif (Array.isArray(data)) {\n\t\t\t\t\tresponseData = data;\n\t\t\t\t} else {\n\t\t\t\t\tresponseData = [data];\n\t\t\t\t}\n\t\t\t} else {","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/nodes-langchain/nodes/tools/ToolHttpRequest/utils.ts#L381-L417","documentation":"Thrown by jsonOptimizer in the AI HTTP Request tool. After parsing the response (or stringifying-then-parsing), if the value is not a non-null object or array — i.e. a primitive string/number/boolean — the optimizer cannot extract fields and throws.","triggerScenarios":"Response Type 'json' selected but the API returns a bare primitive (a quoted string, a single number, true/false); the JSON parses successfully to a non-object value.","commonSituations":"Health-check endpoints returning 'ok' or 200; counters returning an integer; quoting/escaping that makes the body parse as a string scalar instead of an object.","solutions":["If the API genuinely returns a primitive, disable 'Optimize Response' so the default optimizer stringifies it.","Switch Response Type to 'text' to treat the body as a plain string.","Fix the upstream endpoint to return an object/array if JSON field extraction is required."],"exampleFix":"// before: json optimizer against `{ \"status\": 200 }` is fine, but against bare `200` it throws\nresponseType: 'json'\n\n// after (for a primitive-returning API):\noptimizeResponse: false","handlingStrategy":"validation","validationCode":"let parsed: unknown = typeof response === 'string' ? JSON.parse(response) : response;\nif (parsed === null || (typeof parsed !== 'object' && !Array.isArray(parsed))) {\n  parsed = { value: parsed }; // wrap primitives so jsonOptimizer can proceed\n}","typeGuard":"function isJsonObjectOrArray(v: unknown): v is Record<string, unknown> | unknown[] {\n  return typeof v === 'object' && v !== null;\n}","tryCatchPattern":"try { return jsonOptimizer(ctx, itemIndex)(response); }\ncatch (e) { return defaultOptimizer(response); }","preventionTips":["Confirm the API returns an object/array before enabling JSON optimization.","Wrap primitive responses in an object upstream.","Fall back to no optimization for scalar-returning endpoints."],"tags":["http-request-tool","response-optimization","json","ai-tool"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}