Hmbown/CodeWhale · error
Codewhale chat request should succeed
Error message
Codewhale chat request should succeed
What it means
This .expect("Codewhale chat request should succeed") is in crates/tui/src/client.rs:7804. It unwraps create_message() on a CodewhaleClient configured for WireFormat::ChatCompletions against a wiremock server. It panics when the chat-completions request fails — transport error, unexpected status, or response body the client can't parse into a message.
Solutions
- Inspect the panic payload: a status error names the code; a serde error names the field that no longer matches.
- Check the mock: it must accept the model "deepseek/deepseek-v4-pro" and return a valid chat-completions JSON body.
- Verify assert_codewhale_bearer's contract — Authorization: Bearer with the account key, never x-api-key — matches what the client now sends.
- If the wire schema intentionally changed, update both the client mapping and this test's mock/response fixture together.
Example fix
// before
client
.create_message(minimal_zen_request("deepseek/deepseek-v4-pro"))
.await
.expect("Codewhale chat request should succeed");
// after
client
.create_message(minimal_zen_request("deepseek/deepseek-v4-pro"))
.await
.unwrap_or_else(|e| panic!("Codewhale chat request should succeed: {e:?}")); Defensive patterns
Strategy: try-catch
Try / catch
// log the failure detail instead of a bare expect
match client.create_message(minimal_zen_request(model)).await {
Ok(msg) => { /* assertions */ }
Err(e) => panic!("chat request failed: {e:?}"),
} Prevention
- Keep the account key on Authorization: Bearer; never send it as x-api-key on either protocol the account API serves.
- Mirror the ChatCompletions request/response schema in the mock fixture whenever the wire types change.
- After base-URL refactors, confirm the client path still matches the mounted wiremock route.
When it happens
Trigger: Calling client.create_message(minimal_zen_request(...)) where the mounted mock route for ChatCompletions is missing/returns non-2xx or a body that fails deserialization; auth mismatch (the test requires the account key as Authorization: Bearer, never x-api-key) causing a mocked 401; wrong model id in the request path/body.
Common situations: Changing Codewhale's auth header from Bearer to x-api-key so the mock's auth guard rejects it; altering the ChatCompletions request/response schema; pointing the client at an unmocked URL path after a base-URL refactor.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- Codewhale client should resolve its model route
- Codewhale messages request should succeed
- Codewhale responses request should succeed
- Concentrate catalog delta
- create isolated input pipe
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/a7dd3f45e9753b2a.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/client.rs:7804
"object": "chat.completion",
"model": "deepseek/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 = codewhale_client(&server, "deepseek/deepseek-v4-pro");
assert_eq!(client.wire_format, WireFormat::ChatCompletions);
client
.create_message(minimal_zen_request("deepseek/deepseek-v4-pro"))
.await
.expect("Codewhale chat request should succeed");
let requests = server.received_requests().await.expect("recorded request");
assert_eq!(requests.len(), 1);
assert_codewhale_bearer(&requests[0]);
let body: Value = serde_json::from_slice(&requests[0].body).expect("chat JSON body");
// Model ids reach the account API exactly as its catalog returns them.
assert_eq!(
body.get("model").and_then(Value::as_str),
Some("deepseek/deepseek-v4-pro")
);
}
#[tokio::test]
async fn codewhale_messages_request_carries_the_account_bearer_not_x_api_key() {
let server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/v1/messages"))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({View on GitHub (pinned to 73e0f67d83)