Hmbown/CodeWhale · error

Codewhale client should resolve its model route

Error message

Codewhale client should resolve its model route

What it means

This .expect("Codewhale client should resolve its model route") is inside the test helper codewhale_client in crates/tui/src/client.rs:7760. It unwraps CodewhaleClient::new(&config), which resolves the configured model route (e.g. "deepseek/deepseek-v4-pro") through ProvidersConfig/ProviderConfig. It panics when client construction fails — typically because the config doesn't name a provider/model pair the router can resolve.

Solutions

  1. Read the wrapped error from the panic — resolution errors name the missing provider or route.
  2. Ensure the config's model route ("deepseek/deepseek-v4-pro") maps to a provider entry present in ProvidersConfig with the right base URL.
  3. Keep the helper's Config built from ProviderConfig::default()/ProvidersConfig::default() in sync with new required fields added to those types.
  4. Re-run `cargo test -p codewhale-tui codewhale` after adjusting; the helper also fixes wire_format to ChatCompletions.

Example fix

// before
CodewhaleClient::new(&config).expect("Codewhale client should resolve its model route")
// after
CodewhaleClient::new(&config)
    .unwrap_or_else(|e| panic!("Codewhale client should resolve its model route: {e:?}"))
Defensive patterns

Strategy: validation

Validate before calling

// validate the route resolves before building the client
let route = config.providers.resolve_route("deepseek/deepseek-v4-pro");
assert!(route.is_ok(), "model route must resolve before client construction");

Try / catch

// replace expect with error propagation in non-test code
let client = CodewhaleClient::new(&config)
    .map_err(|e| anyhow!("Codewhale client construction failed: {e:?}"))?;

Prevention

When it happens

Trigger: Calling CodewhaleClient::new with a Config whose providers map lacks the provider referenced by the selected model route, or whose ProviderConfig::default() leaves required fields (base URL, auth) unset; also fires if route resolution code rejects the model id format.

Common situations: Renaming provider keys in ProvidersConfig so the route lookup misses; changing CodewhaleClient::new to validate model ids more strictly; copying the helper with a model string no configured provider claims; partial Config::default() usage missing route wiring.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/1829c300b3eea090. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/client.rs:7760

    /// `base_url` goes through the provider table rather than
    /// `CODEWHALE_API_BASE` so the test does not mutate process env, but it
    /// exercises the same "declared origin" path: the key must follow the
    /// route to whatever origin the operator pointed it at.
    fn codewhale_client(server: &MockServer, model: &str) -> CodewhaleClient {
        let config = Config {
            provider: Some("codewhale".to_string()),
            providers: Some(ProvidersConfig {
                codewhale: ProviderConfig {
                    api_key: Some("cwc_key_test_value".to_string()),
                    base_url: Some(server.uri()),
                    model: Some(model.to_string()),
                    ..ProviderConfig::default()
                },
                ..ProvidersConfig::default()
            }),
            ..Config::default()
        };
        CodewhaleClient::new(&config).expect("Codewhale client should resolve its model route")
    }

    /// The account key must ride as `Authorization: Bearer` and never as
    /// `x-api-key`, on both protocols the account API serves.
    fn assert_codewhale_bearer(request: &wiremock::Request) {
        assert_eq!(
            request
                .headers
                .get(AUTHORIZATION)
                .and_then(|value| value.to_str().ok()),
            Some("Bearer cwc_key_test_value")
        );
        assert!(
            request.headers.get("x-api-key").is_none(),
            "the Codewhale API does not accept x-api-key"
        );
    }

View on GitHub (pinned to 73e0f67d83)