{"record":{"id":"d23971f912f59e35","repo":"atuinsh/atuin","slug":"could-not-build-config","errorCode":null,"errorMessage":"Could not build config","messagePattern":"Could not build config","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/atuin-client/src/settings.rs","lineNumber":1158,"sourceCode":"    #[serde(default)]\n    pub logs: Logs,\n\n    #[serde(default)]\n    pub meta: meta::Settings,\n\n    #[serde(default)]\n    pub ai: Ai,\n}\n\nimpl Settings {\n    #[must_use]\n    pub fn utc() -> Self {\n        Self::builder()\n            .expect(\"Could not build default\")\n            .set_override(\"timezone\", \"0\")\n            .expect(\"failed to override timezone with UTC\")\n            .build()\n            .expect(\"Could not build config\")\n            .try_deserialize()\n            .expect(\"Could not deserialize config\")\n    }\n\n    #[must_use]\n    pub fn search_mode(&self) -> SearchMode {\n        self.requested_search_mode.into()\n    }\n\n    pub fn search_mode_shell_up_key_binding(&self) -> Option<SearchMode> {\n        self.requested_search_mode_shell_up_key_binding.map(Into::into)\n    }\n\n    /// Return the active search mode depending on whether Atuin was invoked from the \"up\"\n    /// keybinding.\n    ///\n    /// If Atuin was invoked from the \"up\" keybinding, this returns\n    /// [`Self::search_mode_shell_up_key_binding`], falling back to [`Self::search_mode`] if that","sourceCodeStart":1140,"sourceCodeEnd":1176,"githubUrl":"https://github.com/atuinsh/atuin/blob/900007c48045867e7f44b0f9bc55ad9dbe99ee0d/crates/atuin-client/src/settings.rs#L1140-L1176","documentation":"`Settings::utc()` calls `.build()` on the config and `.expect(\"Could not build config\")` panics if building the merged configuration fails. This merges defaults with overrides; failure means the in-memory configuration is structurally inconsistent. Like the other expects in this constructor, it marks an \"impossible\" internal invariant: default settings must always build.","triggerScenarios":"Calling `Settings::utc()` when `Config::build` fails — e.g. a type mismatch between the default value and the \"timezone\" \"0\" string override introduced by a Settings field type change (deserialization happens later, but build-time coercion of typed values can fail).","commonSituations":"After upgrading atuin-client or the `config` crate where defaults/field types changed so the default+override merge no longer coerces; effectively an upstream regression, not user error.","solutions":["Check for a version mismatch between atuin-client and the `config` crate; align versions.","Inspect the `timezone` field type in Settings — if it changed from string/offset-compatible to a stricter type, the \"0\" override may no longer coerce.","Pin to a known-good atuin-client release where `utc()` works.","File an upstream issue with the panic backtrace; this is an internal invariant failure."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// This is an expect() panic, not a returned error — cannot be matched on.\n// Isolate via catch_unwind when calling library defaults in untrusted embedding contexts:\nlet settings = std::panic::catch_unwind(Settings::default)\n    .map_err(|_| anyhow::anyhow!(\"default settings failed to build; check dependency versions\"))?;","preventionTips":["Pin the `config` crate version used by atuin-client.","After dependency upgrades, run any code path touching Settings in CI to catch build regressions early.","Check Settings field types against their set_default/set_override values."],"tags":["config","panic","internal-invariant"],"backgroundTag":"config-type-mismatch","analyzedSha":"900007c48045867e7f44b0f9bc55ad9dbe99ee0d","analyzedAt":"2026-09-19T12:52:51.491Z","contentChangedAt":"2026-09-19T12:52:51.491Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}