{"record":{"id":"f0bc08a33fad99ad","repo":"n8n-io/n8n","slug":"invalid-hitl-input-for-tool-toolkittool-name","errorCode":null,"errorMessage":"Invalid hitl input for tool ${toolkitTool.name}","messagePattern":"Invalid hitl input for tool (.+?)","errorType":"exception","errorClass":"NodeOperationError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/nodes-langchain/nodes/ToolExecutor/ToolExecutor.node.ts","lineNumber":131,"sourceCode":"\n\t\ttry {\n\t\t\tfor (const tool of toolInputs) {\n\t\t\t\t// Handle toolkits\n\t\t\t\tif (tool && typeof (tool as Toolkit).getTools === 'function') {\n\t\t\t\t\tconst toolsInToolkit = (tool as Toolkit).getTools();\n\t\t\t\t\tfor (const toolkitTool of toolsInToolkit) {\n\t\t\t\t\t\tif (!(toolkitTool instanceof Tool || toolkitTool instanceof StructuredTool)) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (toolName === toolkitTool.name) {\n\t\t\t\t\t\t\tif (hasGatedToolNodeName(toolkitTool.metadata) && node) {\n\t\t\t\t\t\t\t\tconst toolInput: { toolParameters: unknown } = {\n\t\t\t\t\t\t\t\t\ttoolParameters: getQueryData(toolName) ?? {},\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tconst hitlInput = getQueryData(node);\n\t\t\t\t\t\t\t\tif (typeof hitlInput === 'string') {\n\t\t\t\t\t\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\t\t\t\t\t\tthis.getNode(),\n\t\t\t\t\t\t\t\t\t\t`Invalid hitl input for tool ${toolkitTool.name}`,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// handle code tool which uses a string input, but it should be converted to an object\n\t\t\t\t\t\t\t\tconst requiresObjectInput =\n\t\t\t\t\t\t\t\t\ttoolkitTool.metadata.originalSchema &&\n\t\t\t\t\t\t\t\t\ttoolkitTool.metadata.originalSchema instanceof ZodObject;\n\t\t\t\t\t\t\t\tif (typeof toolInput.toolParameters === 'string' && requiresObjectInput) {\n\t\t\t\t\t\t\t\t\ttoolInput.toolParameters = convertValueBySchema(\n\t\t\t\t\t\t\t\t\t\ttoolInput.toolParameters,\n\t\t\t\t\t\t\t\t\t\ttoolkitTool.metadata.originalSchema,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst hitlMetadata = extractHitlMetadata(\n\t\t\t\t\t\t\t\t\ttoolkitTool.metadata,","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/nodes-langchain/nodes/ToolExecutor/ToolExecutor.node.ts#L113-L149","documentation":"Thrown by the ToolExecutor node during gated-tool (human-in-the-loop) handling when the resolved hitl input for the given node is a string rather than an object. Gated tools expect structured approval/parameter data; a string input is not addressable by field and is rejected before being passed to the tool.","triggerScenarios":"Inside the toolkit loop, when toolName === toolkitTool.name, hasGatedToolNodeName(metadata) && node is true, getQueryData(node) returns hitlInput. If `typeof hitlInput === 'string'`, it throws NodeOperationError 'Invalid hitl input for tool <name>'. Fires when the HITL approval payload coming back for the gated node is a plain string.","commonSituations":"The waiting/resume workflow submits a string approval value instead of a JSON object; the front-end or webhook resume payload is malformed; an expression that should yield an object yields its stringified form; mismatch between the gated tool's expected schema and the resume data.","solutions":["Ensure the resume/approval payload for the gated node is a JSON object matching the tool's expected input shape.","If using a Webhook/Form to resume, parse the body into an object before submitting.","Validate the wait-node output schema and align it with what the gated tool expects."],"exampleFix":"// before: hitl resume value = \"approved\"\n// after: hitl resume value = { \"approved\": true, \"comment\": \"ok\" }","handlingStrategy":"type-guard","validationCode":"const hitlInput = getQueryData(node);\nif (typeof hitlInput === 'string') throw new Error('Provide HITL input as a JSON object');","typeGuard":"function isHitlObject(v): v is Record<string, unknown> {\n  return v != null && typeof v === 'object' && !Array.isArray(v);\n}","tryCatchPattern":null,"preventionTips":["Always resume gated tools with a JSON object payload, not a string.","Parse webhook/form resume bodies into objects before submitting.","Align the resume payload schema with the gated tool's expected input."],"tags":["tool-executor","hitl","gated-tool","validation"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}