{"record":{"id":"4c363f64cb668a86","repo":"n8n-io/n8n","slug":"unable-to-convert-tool-to-n8ntool-json-stringif","errorCode":null,"errorMessage":"Unable to convert tool to N8nTool: ${JSON.stringify(tool)}","messagePattern":"Unable to convert tool to N8nTool: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/ai-utilities/src/converters/tool.ts","lineNumber":51,"sourceCode":"\t\tconst structuredTool = tool as LangchainTools.StructuredTool;\n\t\treturn {\n\t\t\ttype: 'function',\n\t\t\tname: structuredTool.name,\n\t\t\tdescription: structuredTool.description,\n\t\t\tinputSchema: structuredTool.schema as JSONSchema7 | ZodTypeAny,\n\t\t};\n\t}\n\tif ('function' in tool && 'type' in tool && tool.type === 'function') {\n\t\tconst functionTool = tool.function as FunctionDefinition;\n\t\treturn {\n\t\t\ttype: 'function',\n\t\t\tname: functionTool.name,\n\t\t\tdescription: functionTool.description,\n\t\t\tinputSchema: functionTool.parameters as JSONSchema7,\n\t\t};\n\t}\n\n\tthrow new Error(`Unable to convert tool to N8nTool: ${JSON.stringify(tool)}`);\n}\n\nexport function getParametersJsonSchema(tool: N8nTools.FunctionTool): JSONSchema7 {\n\tconst schema = tool.inputSchema;\n\tif (schema instanceof ZodSchema) {\n\t\tif ('toJSONSchema' in schema && typeof schema.toJSONSchema === 'function') {\n\t\t\treturn schema.toJSONSchema();\n\t\t}\n\t\treturn zodToJsonSchema(schema) as JSONSchema7;\n\t}\n\treturn schema;\n}\n","sourceCodeStart":33,"sourceCodeEnd":64,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/ai-utilities/src/converters/tool.ts#L33-L64","documentation":"The tool converter accepts a few known tool shapes (Anthropic-style, OpenAI function-calling `{type:'function', function:{...}}`, and a Zod/raw-schema variant handled earlier). Anything that doesn't match one of these discriminators cannot be turned into an N8nTool, so it throws with the serialized input for debugging. This guards the tool-adapter boundary against malformed provider output.","triggerScenarios":"Passing a tool object missing the `function`/`type:'function'` discriminator or the Anthropic fields; a tool shape from a provider format the converter doesn't support; a hand-built object that loosely resembles a tool but lacks required keys.","commonSituations":"A provider returns a non-standard tool descriptor; version skew in provider SDKs changes the tool schema; downstream code forwards an unvalidated object as a tool.","solutions":["Construct tools with the OpenAI shape { type:'function', function:{ name, description, parameters } } or the Anthropic shape the converter expects.","Inspect the serialized tool in the error and add a branch if it's a legitimate new shape.","Validate tool objects at the boundary with a schema before passing them in."],"exampleFix":"// before\n{ name: 'foo', description: '...', parameters: {...} }\n\n// after\n{ type: 'function', function: { name: 'foo', description: '...', parameters: {...} } }","handlingStrategy":"type-guard","validationCode":"function isKnownToolShape(t: unknown): boolean {\n  return (\n    typeof t === 'object' && t !== null && (\n      ('type' in t && (t as { type: string }).type === 'function' && 'function' in t) ||\n      ('name' in t && 'inputSchema' in t)\n    )\n  );\n}\nif (!isKnownToolShape(tool)) throw new Error('unsupported tool shape');","typeGuard":"function isOpenAiFunctionTool(t: unknown): t is { type: 'function'; function: { name: string; description?: string; parameters: object } } {\n  return typeof t === 'object' && t !== null && 'type' in t && (t as { type: string }).type === 'function' && 'function' in t;\n}","tryCatchPattern":null,"preventionTips":["Construct tools with the OpenAI { type:'function', function:{...} } shape.","Validate tools at the boundary before forwarding to the converter.","Re-run the converter's unit tests when changing the tool schema."],"tags":["converters","tools","langchain","validation"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}