Hmbown/CodeWhale · error

OpenCode Zen client should resolve its model route

Error message

OpenCode Zen client should resolve its model route

What it means

This `expect` panics when `CodewhaleClient::new(&config)` returns `Err`, aborting with 'OpenCode Zen client should resolve its model route' at crates/tui/src/client.rs:7946. Client construction validates the providers config and must be able to resolve the configured model to a concrete route (provider, base URL, wire format); if the model id cannot be matched to a catalog offering or provider entry, construction fails.

Solutions

  1. Log the construction error to see which model/provider failed to resolve
  2. Ensure the model id exactly matches a catalog offering (compare with the live snapshot or fixture catalog)
  3. Set `CODEWHALE_HOME` to a fixture home and reset/populate the catalog cache before construction (`reset_cache_for_test`, `record_success` as in the passing tests)
  4. Add the missing provider entry (base_url, api_key, wire format) to `ProvidersConfig`

Example fix

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

Strategy: validation

Validate before calling

// before constructing, verify the model resolves in the catalog
assert!(catalog.offerings.iter().any(|o| o.id == model_id),
    "model {model_id} not present in catalog");

Try / catch

let client = CodewhaleClient::new(&config)
    .unwrap_or_else(|e| panic!("OpenCode Zen client should resolve its model route: {e:?}"));

Prevention

When it happens

Trigger: Calling `CodewhaleClient::new` with a `ProvidersConfig` whose model id (e.g. an `openai/...` or `anthropic/...` name) has no matching provider entry, or whose provider config lacks `base_url`/api-key material needed to resolve the route.

Common situations: Renamed or removed model ids in the provider catalog; a provider namespace (`openai/`) that maps to an unexpected endpoint unless configured; missing `CODEWHALE_HOME` or live-snapshot fixture so the route table is empty; typo'd model strings in test configs.

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/c33ed72c9f1c73da. Report an issue: GitHub.

Appendix: source

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

        crate::provider_catalog_live::reset_cache_for_test();
        crate::provider_lake::clear_live_snapshot();
    }

    fn opencode_zen_client(server: &MockServer, model: &str) -> CodewhaleClient {
        let config = Config {
            provider: Some("opencode-zen".to_string()),
            providers: Some(ProvidersConfig {
                opencode_zen: ProviderConfig {
                    api_key: Some("zen-test-key".to_string()),
                    base_url: Some(server.uri()),
                    model: Some(model.to_string()),
                    ..ProviderConfig::default()
                },
                ..ProvidersConfig::default()
            }),
            ..Config::default()
        };
        CodewhaleClient::new(&config).expect("OpenCode Zen client should resolve its model route")
    }

    fn minimal_zen_request(model: &str) -> MessageRequest {
        translation_message_request("hello", model.to_string(), "English", 4096)
    }

    fn assert_zen_bearer_without_codex_headers(request: &wiremock::Request) {
        assert_eq!(
            request
                .headers
                .get(AUTHORIZATION)
                .and_then(|value| value.to_str().ok()),
            Some("Bearer zen-test-key")
        );
        for forbidden in [
            "openai-beta",
            "originator",
            "chatgpt-account-id",

View on GitHub (pinned to 73e0f67d83)