{"record":{"id":"50e141787502f6d0","repo":"Hmbown/CodeWhale","slug":"unknown-feature-flag-key","errorCode":null,"errorMessage":"Unknown feature flag: {key}","messagePattern":"Unknown feature flag: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/config.rs","lineNumber":4385,"sourceCode":"        match validate_kimi_code_api_model_id(\n            active_provider,\n            &self.deepseek_base_url(),\n            &self.default_model(),\n        ) {\n            Err(error) if error == KIMI_CODE_CLAUDE_ALIAS_GUIDANCE => {\n                return Err(SafeConfigDiagnostic::KimiCodeClaudeAlias.into());\n            }\n            result => result.map_err(anyhow::Error::msg)?,\n        }\n        if let Some(ref key) = self.api_key\n            && key.trim().is_empty()\n        {\n            anyhow::bail!(\"api_key cannot be empty string\");\n        }\n        if let Some(features) = &self.features {\n            for key in features.entries.keys() {\n                if !is_known_feature_key(key) {\n                    anyhow::bail!(\"Unknown feature flag: {key}\");\n                }\n            }\n        }\n        // Validate the model against the *active provider's* name space, not\n        // against DeepSeek's. `canonical_model_id_for_provider` is the\n        // equal-treatment resolver: it applies each family's own canonical map\n        // (GLM via Z.ai, Kimi, MiniMax, …) and passes unknown ids through, so\n        // it rejects only what the provider genuinely cannot serve. Validating\n        // with the DeepSeek-only `normalize_model_name` bricked every config\n        // whose provider owns a non-DeepSeek family — including ones our own\n        // setup wizard writes (`provider = \"zai\"`, `GLM-5.2`). (#4829)\n        if let Some(model) = self.default_text_model.as_deref()\n            && !model.trim().eq_ignore_ascii_case(\"auto\")\n            && !provider_passes_model_through(self.api_provider())\n            && !self.active_provider_preserves_custom_base_url_model()\n            && canonical_model_id_for_provider(self.api_provider(), model).is_none()\n        {\n            let provider = self.api_provider();","sourceCodeStart":4367,"sourceCodeEnd":4403,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/config.rs#L4367-L4403","documentation":"Config validation (crates/tui/src/config.rs:4385) iterates the [features] table and rejects any key that is_known_feature_key does not recognize. Feature flags gate real code paths, so an unknown key (typo or retired flag) fails load instead of silently doing nothing.","triggerScenarios":"A typo'd flag name (beter_context vs better_context); a flag renamed or removed in an upgrade; flags copied from newer-version docs into an older binary.","commonSituations":"Version skew between docs and the installed binary; hand-merging feature sections between configs; flags that existed in forks.","solutions":["Check the release notes/CHANGELOG for the exact current flag names","Fix or remove the typo'd key from [features]","If the flag was retired, delete it - its behavior is either default or gone","Upgrade the binary if the docs you copied from are newer than what you run"],"exampleFix":"# config.toml - before\n[features]\nbeter_context = true\n\n# config.toml - after\n[features]\nbetter_context = true\n","handlingStrategy":"validation","validationCode":"for key in features_map.keys() {\n    ensure!(is_known_feature_key(key), \"unknown feature flag {key}\");\n}","typeGuard":"fn feature_flag_known(key: &str, known: &[&str]) -> bool { known.contains(&key) }","tryCatchPattern":"// In config tooling: filter flags against the running binary's known set\nlet unknown: Vec<_> = cfg.features.entries.keys().filter(|k| !is_known_feature_key(k)).collect();\nif !unknown.is_empty() { bail!(\"unknown flags: {unknown:?}\"); }","preventionTips":["Copy flag names from the docs matching your binary's version","Diff [features] against the CHANGELOG when upgrading","A typo'd flag fails the whole config load - lint it before launch"],"tags":["config","feature-flags","validation","typo"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}