continuedev/continue · error · Error
Unsupported tool type in Anthropic: ${tool.type}
Error message
Unsupported tool type in Anthropic: ${tool.type} What it means
openaiToolToAnthropicTool only accepts tools with type 'function'. Any other OpenAI tool type reaches the else branch and throws with the offending type name. Anthropic's tool schema has no representation for non-function tool types.
Source
Thrown at packages/openai-adapters/src/apis/AnthropicUtils.ts:166
return undefined; // TODO not supported yet
case "function":
return {
type: "tool",
name: toolChoice.function.name,
};
}
}
}
export function openaiToolToAnthropicTool(tool: ChatCompletionTool): Tool {
if (tool.type === "function" && "function" in tool) {
return {
name: tool.function.name,
description: tool.function.description,
input_schema: tool.function.parameters as Tool.InputSchema, // TODO unsafe cast, may be differences between openai tool schema and anthropic tool schema,
};
} else {
throw new Error(`Unsupported tool type in Anthropic: ${tool.type}`);
}
}
// Extract media type from data URL (ex. "data:image/png;base64,..." -> "image/png")
export function getAnthropicMediaTypeFromDataUrl(
dataUrl: string,
): Base64ImageSource["media_type"] {
const match = dataUrl.match(/^data:([^;]+);base64,/);
if (match) {
switch (match[1]) {
case "image/png":
case "image/gif":
case "image/webp":
return match[1];
}
}
return "image/jpeg";
}View on GitHub (pinned to 5522c6f44c)
Solutions
- Ensure every tool in the tools array has type:'function' with a valid function:{name,description,parameters}
- Filter out non-function tools before calling the adapter
- Validate tool definitions against the OpenAI function-tool schema before sending
Example fix
// before
const tools = [{ type: 'code_interpreter' }];
await api.chatCompletionNonStream({ model, messages, tools });
// after
const tools = [{ type: 'function', function: { name: 'get_weather', description: '...', parameters: { type: 'object', properties: {} } } }];
await api.chatCompletionNonStream({ model, messages, tools }); Defensive patterns
Strategy: validation
Validate before calling
const ok = tools.every(t => t.type === 'function' && t.function?.name);
Type guard
function isOpenAiFunctionTool(t: any): t is { type: 'function'; function: { name: string } } {
return t?.type === 'function' && typeof t.function?.name === 'string';
} Try / catch
try { return await api.chatCompletionNonStream({ ...body, tools }, signal); }
catch (e) { if (/Unsupported tool type/.test(String(e))) { throw new Error(`Filter non-function tools: ${e.message}`); } throw e; } Prevention
- Filter tools with tools.filter(isOpenAiFunctionTool) before every call
- Define tools in one place with type:'function' enforced by types/tests
When it happens
Trigger: Passing tools:[{type: 'custom'|'code_interpreter'|...}] in chatCompletionStream/NonStream to the Anthropic adapter; anything other than type:'function' triggers the throw.
Common situations: Reusing OpenAI tool definitions (e.g. with newer tool types) against Claude; malformed tool objects missing the type field (undefined type); providers emitting non-standard tool types.
Related errors
- No tool use found
- Unsupported tool type: ${tool.type}
- Error getting prompt: MCP Connection ${serverName} not found
- Failed to fetch Anthropic models: ${response.status}
- Invalid MCP server configuration
AI-assisted analysis of continuedev/continue@5522c6f44c (2026-08-27).
Data as JSON: /api/errors/e1023501e99b5142.
Report an issue: GitHub.