{"record":{"id":"e1023501e99b5142","repo":"continuedev/continue","slug":"unsupported-tool-type-in-anthropic-tool-type","errorCode":null,"errorMessage":"Unsupported tool type in Anthropic: ${tool.type}","messagePattern":"Unsupported tool type in Anthropic: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/openai-adapters/src/apis/AnthropicUtils.ts","lineNumber":166,"sourceCode":"          return undefined; // TODO not supported yet\n        case \"function\":\n          return {\n            type: \"tool\",\n            name: toolChoice.function.name,\n          };\n      }\n  }\n}\n\nexport function openaiToolToAnthropicTool(tool: ChatCompletionTool): Tool {\n  if (tool.type === \"function\" && \"function\" in tool) {\n    return {\n      name: tool.function.name,\n      description: tool.function.description,\n      input_schema: tool.function.parameters as Tool.InputSchema, // TODO unsafe cast, may be differences between openai tool schema and anthropic tool schema,\n    };\n  } else {\n    throw new Error(`Unsupported tool type in Anthropic: ${tool.type}`);\n  }\n}\n\n// Extract media type from data URL (ex. \"data:image/png;base64,...\" -> \"image/png\")\nexport function getAnthropicMediaTypeFromDataUrl(\n  dataUrl: string,\n): Base64ImageSource[\"media_type\"] {\n  const match = dataUrl.match(/^data:([^;]+);base64,/);\n  if (match) {\n    switch (match[1]) {\n      case \"image/png\":\n      case \"image/gif\":\n      case \"image/webp\":\n        return match[1];\n    }\n  }\n  return \"image/jpeg\";\n}","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/continuedev/continue/blob/5522c6f44ca0ac3528b37244818fbfa39b5af470/packages/openai-adapters/src/apis/AnthropicUtils.ts#L148-L184","documentation":"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.","triggerScenarios":"Passing tools:[{type: 'custom'|'code_interpreter'|...}] in chatCompletionStream/NonStream to the Anthropic adapter; anything other than type:'function' triggers the throw.","commonSituations":"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.","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"],"exampleFix":"// before\nconst tools = [{ type: 'code_interpreter' }];\nawait api.chatCompletionNonStream({ model, messages, tools });\n\n// after\nconst tools = [{ type: 'function', function: { name: 'get_weather', description: '...', parameters: { type: 'object', properties: {} } } }];\nawait api.chatCompletionNonStream({ model, messages, tools });","handlingStrategy":"validation","validationCode":"const ok = tools.every(t => t.type === 'function' && t.function?.name);","typeGuard":"function isOpenAiFunctionTool(t: any): t is { type: 'function'; function: { name: string } } {\n  return t?.type === 'function' && typeof t.function?.name === 'string';\n}","tryCatchPattern":"try { return await api.chatCompletionNonStream({ ...body, tools }, signal); }\ncatch (e) { if (/Unsupported tool type/.test(String(e))) { throw new Error(`Filter non-function tools: ${e.message}`); } throw e; }","preventionTips":["Filter tools with tools.filter(isOpenAiFunctionTool) before every call","Define tools in one place with type:'function' enforced by types/tests"],"tags":["anthropic","tool-calls","schema-validation"],"backgroundTag":"unsupported-tool-type","analyzedSha":"5522c6f44ca0ac3528b37244818fbfa39b5af470","analyzedAt":"2026-08-27T11:28:54.683Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}