{"record":{"id":"1829c300b3eea090","repo":"Hmbown/CodeWhale","slug":"codewhale-client-should-resolve-its-model-route","errorCode":null,"errorMessage":"Codewhale client should resolve its model route","messagePattern":"Codewhale client should resolve its model route","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/client.rs","lineNumber":7760,"sourceCode":"    /// `base_url` goes through the provider table rather than\n    /// `CODEWHALE_API_BASE` so the test does not mutate process env, but it\n    /// exercises the same \"declared origin\" path: the key must follow the\n    /// route to whatever origin the operator pointed it at.\n    fn codewhale_client(server: &MockServer, model: &str) -> CodewhaleClient {\n        let config = Config {\n            provider: Some(\"codewhale\".to_string()),\n            providers: Some(ProvidersConfig {\n                codewhale: ProviderConfig {\n                    api_key: Some(\"cwc_key_test_value\".to_string()),\n                    base_url: Some(server.uri()),\n                    model: Some(model.to_string()),\n                    ..ProviderConfig::default()\n                },\n                ..ProvidersConfig::default()\n            }),\n            ..Config::default()\n        };\n        CodewhaleClient::new(&config).expect(\"Codewhale client should resolve its model route\")\n    }\n\n    /// The account key must ride as `Authorization: Bearer` and never as\n    /// `x-api-key`, on both protocols the account API serves.\n    fn assert_codewhale_bearer(request: &wiremock::Request) {\n        assert_eq!(\n            request\n                .headers\n                .get(AUTHORIZATION)\n                .and_then(|value| value.to_str().ok()),\n            Some(\"Bearer cwc_key_test_value\")\n        );\n        assert!(\n            request.headers.get(\"x-api-key\").is_none(),\n            \"the Codewhale API does not accept x-api-key\"\n        );\n    }\n","sourceCodeStart":7742,"sourceCodeEnd":7778,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/client.rs#L7742-L7778","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the wrapped error from the panic — resolution errors name the missing provider or route.","Ensure the config's model route (\"deepseek/deepseek-v4-pro\") maps to a provider entry present in ProvidersConfig with the right base URL.","Keep the helper's Config built from ProviderConfig::default()/ProvidersConfig::default() in sync with new required fields added to those types.","Re-run `cargo test -p codewhale-tui codewhale` after adjusting; the helper also fixes wire_format to ChatCompletions."],"exampleFix":"// before\nCodewhaleClient::new(&config).expect(\"Codewhale client should resolve its model route\")\n// after\nCodewhaleClient::new(&config)\n    .unwrap_or_else(|e| panic!(\"Codewhale client should resolve its model route: {e:?}\"))","handlingStrategy":"validation","validationCode":"// validate the route resolves before building the client\nlet route = config.providers.resolve_route(\"deepseek/deepseek-v4-pro\");\nassert!(route.is_ok(), \"model route must resolve before client construction\");","typeGuard":null,"tryCatchPattern":"// replace expect with error propagation in non-test code\nlet client = CodewhaleClient::new(&config)\n    .map_err(|e| anyhow!(\"Codewhale client construction failed: {e:?}\"))?;","preventionTips":["Keep ProvidersConfig/ProviderConfig defaults updated whenever a required field is added.","Ensure every model id used in tests maps to a provider key in the fixture config.","Fail loud at config load (per repo convention) if a referenced provider is missing."],"tags":["rust","test","config","client-construction"],"backgroundTag":"invalid-config-value","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}