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
- Register the tool as a function tool with a JSON Schema input instead
- Disable the custom tool/extension for LM Studio models
- Route tool-heavy agents to a provider with custom-tool support
- 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
- Gate custom tools on provider capability checks in your tool registry
- Default to function tools with JSON Schemas for portability across local servers
- Fail with an actionable message at tool-registration time instead of mid-request
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
- llama.cpp does not support custom tools
- Bedrock does not support custom tools
- DeepSeek does not support custom tools
- $ref target not found in {defs_key}: {ref_str}
- Unsupported $ref format (only `#/$defs/<name>` and `#/defini
AI-assisted analysis of zed-industries/zed@5a9b9558db (2026-08-20).
Data as JSON: /api/errors/e127f90058306ca8.
Report an issue: GitHub.