zed-industries/zed · error · anyhow::Error
Bedrock does not support custom tools
Error message
Bedrock does not support custom tools
What it means
into_bedrock converts a LanguageModelRequest into a Bedrock converse request and hard-rejects requests whose contains_custom_tool_input() is true: Bedrock's toolConfig accepts only JSON-schema function tools, so Zed's freeform 'custom' tool variant cannot be translated. The check runs first, before any message conversion.
Source
Thrown at crates/language_models/src/provider/bedrock.rs:1976
}
other => other,
}
})
}
pub fn into_bedrock(
request: LanguageModelRequest,
model: String,
default_temperature: f32,
max_output_tokens: u64,
thinking_mode: BedrockModelMode,
supports_caching: bool,
supports_tool_use: bool,
guardrail_identifier: Option<String>,
guardrail_version: Option<String>,
) -> Result<bedrock::Request> {
if request.contains_custom_tool_input() {
anyhow::bail!("Bedrock does not support custom tools");
}
let mut new_messages: Vec<BedrockMessage> = Vec::new();
let mut system_message = String::new();
// Track whether messages contain tool content - Bedrock requires toolConfig
// when tool blocks are present, so we may need to add a dummy tool
let mut messages_contain_tool_content = false;
for message in request.messages {
if message.contents_empty() {
continue;
}
match message.role {
Role::User | Role::Assistant => {
let mut bedrock_message_content: Vec<BedrockInnerContent> = message
.contentView on GitHub (pinned to f4178619ac)
Solutions
- Switch the tool to a function-style tool (LanguageModelRequestToolInput::Function with a JSON input schema)
- Disable the custom tool / extension before using a Bedrock model
- Use a provider that supports custom tools (e.g. Anthropic direct) for that agent
- Gate the feature in extension code on the current model's tool capabilities
Example fix
// before
if request.contains_custom_tool_input() {
anyhow::bail!("Bedrock does not support custom tools");
}
// after (caller-side guard)
if model.provider_is_bedrock() && request.contains_custom_tool_input() {
request.tools.retain(|tool| matches!(tool.input, LanguageModelRequestToolInput::Function { .. }));
} Defensive patterns
Strategy: validation
Validate before calling
if provider.is_bedrock() && request.contains_custom_tool_input() {
anyhow::bail!("custom tools unsupported for Bedrock; falling back to function tools");
// or: request.tools.retain(|t| matches!(t.input, LanguageModelRequestToolInput::Function { .. }));
} Type guard
fn is_function_only_request(request: &LanguageModelRequest) -> bool {
!request.contains_custom_tool_input()
} Try / catch
match into_bedrock(request.clone(), ... ) {
Ok(bedrock_request) => send(bedrock_request).await,
Err(e) if e.to_string().contains("custom tools") => disable_custom_tools_and_retry().await,
Err(e) => Err(e),
} Prevention
- Check contains_custom_tool_input() in the dispatch layer before choosing the provider
- Author shared tools as function tools with JSON Schemas — the universally supported shape
- Advertise capability per model and let the UI gray out incompatible tool+model combinations
When it happens
Trigger: Selecting an AWS Bedrock model while a custom (prompt-style) tool is active in the request — e.g. an agent/tool extension that registers a Custom tool input instead of a Function with an input_schema.
Common situations: Enabling tools built for providers with custom-tool support (Anthropic direct, OpenAI) and then switching the model to Bedrock; extension upgrades adding custom tools to flows that also run on Bedrock.
Related errors
- DeepSeek does not support custom tools
- llama.cpp does not support custom tools
- LM Studio does not support custom tools
- invalid model id {id}
- $ref target not found in {defs_key}: {ref_str}
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/1675337937ba38c3.
Report an issue: GitHub.