n8n-io/n8n · error · Error
Unable to convert tool to N8nTool: ${JSON.stringify(tool)}
Error message
Unable to convert tool to N8nTool: ${JSON.stringify(tool)} What it means
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.
Source
Thrown at packages/@n8n/ai-utilities/src/converters/tool.ts:51
const structuredTool = tool as LangchainTools.StructuredTool;
return {
type: 'function',
name: structuredTool.name,
description: structuredTool.description,
inputSchema: structuredTool.schema as JSONSchema7 | ZodTypeAny,
};
}
if ('function' in tool && 'type' in tool && tool.type === 'function') {
const functionTool = tool.function as FunctionDefinition;
return {
type: 'function',
name: functionTool.name,
description: functionTool.description,
inputSchema: functionTool.parameters as JSONSchema7,
};
}
throw new Error(`Unable to convert tool to N8nTool: ${JSON.stringify(tool)}`);
}
export function getParametersJsonSchema(tool: N8nTools.FunctionTool): JSONSchema7 {
const schema = tool.inputSchema;
if (schema instanceof ZodSchema) {
if ('toJSONSchema' in schema && typeof schema.toJSONSchema === 'function') {
return schema.toJSONSchema();
}
return zodToJsonSchema(schema) as JSONSchema7;
}
return schema;
}
View on GitHub (pinned to 5ac6606e81)
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.
Example fix
// before
{ name: 'foo', description: '...', parameters: {...} }
// after
{ type: 'function', function: { name: 'foo', description: '...', parameters: {...} } } Defensive patterns
Strategy: type-guard
Validate before calling
function isKnownToolShape(t: unknown): boolean {
return (
typeof t === 'object' && t !== null && (
('type' in t && (t as { type: string }).type === 'function' && 'function' in t) ||
('name' in t && 'inputSchema' in t)
)
);
}
if (!isKnownToolShape(tool)) throw new Error('unsupported tool shape'); Type guard
function isOpenAiFunctionTool(t: unknown): t is { type: 'function'; function: { name: string; description?: string; parameters: object } } {
return typeof t === 'object' && t !== null && 'type' in t && (t as { type: string }).type === 'function' && 'function' in t;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Deferred tool name "${tool.name}" is reserved
- Duplicate deferred tool name "${tool.name}"
- ${toolName} policy.maxChildren must be a finite positive int
- ${toolName} policy.maxChildren must be at least 1
- Provided message is not a valid Langchain message: ${JSON.st
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/4c363f64cb668a86.
Report an issue: GitHub.