Hmbown/CodeWhale · error
Zen Chat Completions request should succeed
Error message
Zen Chat Completions request should succeed
What it means
Test-side `.expect("Zen Chat Completions request should succeed")` panic. `create_message` returned `Err` for a `WireFormat::ChatCompletions` client against the mocked `/v1/chat/completions` endpoint. The OpenAI-compatible chat completion path failed before completion — send failure, wrong route, or the mock's chat-completion JSON no longer parses into the client's response type.
Solutions
- Print the underlying error (`{e:?}`) to see send vs. parse failure.
- Verify the mock at `POST /v1/chat/completions` returns the complete fixture including `object`, `created`, `choices` and `usage`.
- Confirm `client.wire_format == WireFormat::ChatCompletions` (asserted above).
- Check auth: ChatCompletions uses `authorization: Bearer ...` and must not carry `anthropic-version`.
Example fix
// before
client
.create_message(minimal_zen_request("deepseek-v4-pro"))
.await
.expect("Zen Chat Completions request should succeed");
// after
client
.create_message(minimal_zen_request("deepseek-v4-pro"))
.await
.unwrap_or_else(|e| panic!("Zen Chat Completions request should succeed: {e:?}")); Defensive patterns
Strategy: try-catch
Validate before calling
// Rust (preconditions)
assert_eq!(client.wire_format, WireFormat::ChatCompletions);
assert!(fixture["choices"].as_array().map_or(false, |c| !c.is_empty()));
assert!(fixture.get("usage").is_some()); Try / catch
match client.create_message(req).await {
Ok(msg) => assert!(!msg.content.is_empty()),
Err(e) => panic!("Chat Completions request should succeed: {e:?}"),
} Prevention
- Keep the chat-completions fixture schema-complete (object, created, choices, usage).
- Keep model-to-wire routing table and test model names in sync.
- Print the error chain in panics to separate transport from parse failures.
- Assert Bearer auth and absence of anthropic-version on this wire.
When it happens
Trigger: Running `opencode_zen_chat_request_uses_chat_completions_route` when the mock path no longer matches, deepseek-v4-pro no longer resolves to ChatCompletions, or the fixture (missing `created`, `object`, `choices[].finish_reason`, `usage`) fails response parsing.
Common situations: Tightening the ChatCompletions response deserializer; renaming models in the route table so the test model falls to another wire; edited mock fixture dropping required fields.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Absolute path should not warn
- child assignment
- child-local search
- Codewhale chat request should succeed
- configured Web evidence tool
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/6a312c8e806e79f8.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/client.rs:8209
"object": "chat.completion",
"model": "deepseek-v4-pro",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "ok"},
"finish_reason": "stop"
}],
"usage": {"prompt_tokens": 1, "completion_tokens": 1, "total_tokens": 2}
})))
.expect(1)
.mount(&server)
.await;
let client = opencode_zen_client(&server, "deepseek-v4-pro");
assert_eq!(client.wire_format, WireFormat::ChatCompletions);
client
.create_message(minimal_zen_request("deepseek-v4-pro"))
.await
.expect("Zen Chat Completions request should succeed");
let requests = server.received_requests().await.expect("recorded request");
assert_eq!(requests.len(), 1);
assert_zen_bearer_without_codex_headers(&requests[0]);
assert!(requests[0].headers.get("anthropic-version").is_none());
}
#[tokio::test]
async fn opencode_zen_client_fails_closed_when_request_model_changes_protocol() {
let server = MockServer::start().await;
let client = opencode_zen_client(&server, "gpt-5.5");
let error = client
.create_message(minimal_zen_request("claude-sonnet-4-6"))
.await
.expect_err("a Responses-bound client must not send a Messages model");
assert!(format!("{error:#}").contains("resolve a new model route"));
assert!(View on GitHub (pinned to 73e0f67d83)