zeroclaw-labs/zeroclaw · error · anyhow::Error
Failed to parse Ollama response: {e}
Error message
Failed to parse Ollama response: {e} What it means
Ollama returned a 2xx response, but the body failed to deserialize into the ChatResponse shape the provider expects (send_request_inner). The preceding WARN log records the deserialization error plus a body_excerpt, so the exact offending payload is recoverable from logs. This is schema drift between what Ollama returned and what this ZeroClaw build parses.
Source
Thrown at crates/zeroclaw-providers/src/ollama.rs:760
sanitized
);
}
let chat_response: ApiChatResponse = match serde_json::from_slice(&body) {
Ok(r) => r,
Err(e) => {
let raw = String::from_utf8_lossy(&body);
let sanitized = super::sanitize_api_error(&raw);
::zeroclaw_log::record!(
ERROR,
::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Fail)
.with_outcome(::zeroclaw_log::EventOutcome::Failure),
&format!(
"Ollama response deserialization failed: {e}. body_excerpt={}",
sanitized
)
);
anyhow::bail!("Failed to parse Ollama response: {e}");
}
};
Ok(chat_response)
}
async fn send_request(
&self,
messages: Vec<Message>,
model: &str,
temperature: Option<f64>,
should_auth: bool,
tools: Option<&[serde_json::Value]>,
) -> anyhow::Result<ApiChatResponse> {
let result = self
.send_request_inner(
&messages,
model,View on GitHub (pinned to 88bb9c8533)
Solutions
- Pull the WARN log line 'Ollama response deserialization failed: ... body_excerpt=...' and inspect the actual payload.
- Align versions: upgrade ZeroClaw to the release matching your Ollama version, or pin Ollama to the version the provider was built against.
- Remove intermediaries so the provider talks directly to Ollama's /api/chat.
- Confirm base_url is the Ollama native API root (e.g. http://localhost:11434), not an OpenAI-compatible /v1 endpoint.
Example fix
# before — OpenAI-compat shim behind the same port; wrong response shape [providers.models.ollama.local] base_url = "http://localhost:11434/v1" # after — native Ollama API root [providers.models.ollama.local] base_url = "http://localhost:11434"
Defensive patterns
Strategy: try-catch
Validate before calling
# Smoke-test the wire shape before starting long jobs
curl -s http://localhost:11434/api/chat -d '{"model":"llama3","messages":[{"role":"user","content":"ping"}],"stream":false}' | jq -e '.message.content' >/dev/null && echo shape-ok Try / catch
Catch the parse failure, then read the paired WARN log ('Ollama response deserialization failed: ... body_excerpt=...') to see the exact payload. Fix the shape mismatch (version drift, proxy, wrong base_url) instead of retrying — the response will fail identically. Prevention
- Pin the Ollama version in dev and CI
- Keep base_url pointed directly at Ollama; no reverse proxy on /api/chat
- Run a one-message smoke chat after upgrading either Ollama or ZeroClaw
When it happens
Trigger: An Ollama upgrade adds/renames fields the parser treats as required; a reverse proxy in front of Ollama rewrites the JSON or substitutes a 200 HTML page; base_url targets a non-Ollama server whose /api/chat response shape differs.
Common situations: Upgrading Ollama ahead of the ZeroClaw version's schema (or vice versa); routing Ollama through a gateway that mangles bodies; pointing base_url at an OpenAI-compat shim that answers /api/chat with the wrong shape.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Ollama API error ({}): {}. Is Ollama running? (brew install
- Schema missing required 'type' field
- providers.models.ollama.{alias}.model uses ':cloud', but uri
- providers.models.ollama.{alias}.model uses ':cloud', but no
- Model '{}' requested cloud routing, but Ollama endpoint is l
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/3a6f568f3442b408.
Report an issue: GitHub.