atuinsh/atuin · warning

Could not deserialize config

Error message

Could not deserialize config

What it means

`Settings::utc()` finishes with `.try_deserialize().expect("Could not deserialize config")`, panicking if the built config cannot be deserialized into the `Settings` struct. Since the config was built purely from defaults plus the timezone override, this fires only if the default values themselves violate Settings' field types/validation.

Solutions

  1. Check the `timezone` field type in Settings; if it no longer accepts "0", update the override (e.g. "UTC").
  2. Verify defaults and the Settings struct are from the same version — rebuild with a consistent checkout.
  3. Look for recently changed serde attributes (deny_unknown_fields, enum variants) that broke default deserialization.
  4. Report upstream; defaults must always deserialize.

Example fix

// before
.set_override("timezone", "0")

// after (if timezone field became an enum/offset type)
.set_override("timezone", "UTC")
Defensive patterns

Strategy: try-catch

Try / catch

// expect() panic — match via catch_unwind and fall back:
let settings = std::panic::catch_unwind(Settings::utc)
    .map_err(|_| anyhow::anyhow!("utc() deserialization failed; Settings schema/defaults mismatch"))?;

Prevention

When it happens

Trigger: Calling `Settings::utc()` when a default field value fails deserialization into its target type (e.g. an enum default missing a serde variant, or the "0" timezone override failing to parse into the timezone type).

Common situations: Version drift where Settings' serde model changed but defaults did not; overriding timezone "0" against a field now typed as a named offset rather than a numeric string.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of atuinsh/atuin@900007c480 (2026-09-19). Data as JSON: /api/errors/ac6cf0980a2d57f2. Report an issue: GitHub.

Appendix: source

Thrown at crates/atuin-client/src/settings.rs:1160

    #[serde(default)]
    pub meta: meta::Settings,

    #[serde(default)]
    pub ai: Ai,
}

impl Settings {
    #[must_use]
    pub fn utc() -> Self {
        Self::builder()
            .expect("Could not build default")
            .set_override("timezone", "0")
            .expect("failed to override timezone with UTC")
            .build()
            .expect("Could not build config")
            .try_deserialize()
            .expect("Could not deserialize config")
    }

    #[must_use]
    pub fn search_mode(&self) -> SearchMode {
        self.requested_search_mode.into()
    }

    pub fn search_mode_shell_up_key_binding(&self) -> Option<SearchMode> {
        self.requested_search_mode_shell_up_key_binding.map(Into::into)
    }

    /// Return the active search mode depending on whether Atuin was invoked from the "up"
    /// keybinding.
    ///
    /// If Atuin was invoked from the "up" keybinding, this returns
    /// [`Self::search_mode_shell_up_key_binding`], falling back to [`Self::search_mode`] if that
    /// binding isn't defined. Otherwise, [`Self::search_mode`] is returned.
    #[must_use]

View on GitHub (pinned to 900007c480)