zed-industries/zed · error · anyhow::Error

LM Studio does not support custom tools

Error message

LM Studio does not support custom tools

What it means

LmStudioLanguageModel::to_lmstudio_request applies the same guard as the other OpenAI-compatible converters: LM Studio's API models function tools only, so contains_custom_tool_input() == true aborts request construction before any messages are serialized.

Source

Thrown at crates/language_models/src/provider/lmstudio.rs:338

        ))
    }
}

pub struct LmStudioLanguageModel {
    id: LanguageModelId,
    model: lmstudio::Model,
    http_client: Arc<dyn HttpClient>,
    request_limiter: RateLimiter,
    state: Entity<State>,
}

impl LmStudioLanguageModel {
    fn to_lmstudio_request(
        &self,
        request: LanguageModelRequest,
    ) -> Result<lmstudio::ChatCompletionRequest> {
        if request.contains_custom_tool_input() {
            anyhow::bail!("LM Studio does not support custom tools");
        }

        let mut messages = Vec::new();

        for message in request.messages {
            for content in message.content {
                match content {
                    MessageContent::Text(text) => add_message_content_part(
                        lmstudio::MessagePart::Text { text },
                        message.role,
                        &mut messages,
                    ),
                    MessageContent::Thinking { .. } => {}
                    MessageContent::RedactedThinking(_) => {}
                    MessageContent::Compaction(_) => {}
                    MessageContent::Image(image) => {
                        add_message_content_part(
                            lmstudio::MessagePart::Image {

View on GitHub (pinned to 5a9b9558db)

Solutions

  1. Register the tool as a function tool with a JSON Schema input instead
  2. Disable the custom tool/extension for LM Studio models
  3. Route tool-heavy agents to a provider with custom-tool support
  4. Pre-check contains_custom_tool_input() in your dispatch layer and degrade gracefully
Defensive patterns

Strategy: validation

Validate before calling

if self.model.is_lmstudio() && request.contains_custom_tool_input() {
    anyhow::bail!("LM Studio accepts function tools only");
}

Type guard

fn is_function_only_request(request: &LanguageModelRequest) -> bool {
    !request.contains_custom_tool_input()
}

Try / catch

match self.to_lmstudio_request(request) {
    Ok(req) => Ok(self.stream(req).await?),
    Err(e) if e.to_string().contains("custom tools") => self.stream(request_without_custom_tools()).await,
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Selecting an LM Studio-hosted local model while the request carries a custom (non-function) tool — typically an agent or extension that registered a Custom tool input.

Common situations: Local LM Studio setups combined with agents authored for cloud providers; toggling a tool-bearing assistant between providers; extension updates introducing custom tools into existing flows.

Related errors


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