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
                    .content

View on GitHub (pinned to f4178619ac)

Solutions

  1. Switch the tool to a function-style tool (LanguageModelRequestToolInput::Function with a JSON input schema)
  2. Disable the custom tool / extension before using a Bedrock model
  3. Use a provider that supports custom tools (e.g. Anthropic direct) for that agent
  4. 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

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


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/1675337937ba38c3. Report an issue: GitHub.