atuinsh/atuin · warning

Could not build default

Error message

Could not build default

What it means

`impl Default for Settings` builds the configuration purely from programmatic defaults (no user config file) and `.expect("Could not build default")` panics if `Settings::builder()` itself fails. The builder's job is to assemble default sources; failure means default values could not even be attached, which the code comments acknowledge means "something is very wrong".

Solutions

  1. Diff `Settings::builder()` against its last working version; a recently added ConfigBuilder step likely errors.
  2. Check the `config` crate version for behavioral changes in builder/source APIs; pin or adapt.
  3. Run with RUST_BACKTRACE=1 to locate which builder step fails.
  4. Report upstream — Default must always construct.
Defensive patterns

Strategy: try-catch

Try / catch

// Panic-based; isolate if embedding:
let settings = std::panic::catch_unwind(Settings::default)
    .map_err(|_| anyhow::anyhow!("Settings::builder() failed; internal invariant broken"))?;

Prevention

When it happens

Trigger: Calling `Settings::default()` (or anything that falls back to it) when `Settings::builder()` returns Err — e.g. the builder cannot add its default sources, or an environment-dependent step inside builder() (env prefix setup, source loading) errors.

Common situations: Only after code changes to `Settings::builder()` or the `config` crate: a renamed env var prefix, a broken config source path, or a dependency regression. Not reachable through user configuration.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

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

            .add_source(ConfigFile::from_str(toml, FileFormat::Toml))
            .build()?;

        let settings: Self = config.try_deserialize()?;
        if let Some(dir) = &settings.data_dir {
            shellexpand::full(dir).map_err(ValidationError::DataDir)?;
        }

        settings.ui.validate()?;
        Ok(())
    }
}

impl Default for Settings {
    fn default() -> Self {
        // if this panics something is very wrong, as the default config
        // does not build or deserialize into the settings struct
        Self::builder()
            .expect("Could not build default")
            .build()
            .expect("Could not build config")
            .try_deserialize()
            .expect("Could not deserialize config")
    }
}

/// Error returned by [`Settings::validate_str`] when validation fails.
#[derive(Debug, Error)]
pub enum ValidationError {
    #[error(transparent)]
    Config(#[from] config::ConfigError),

    #[error(transparent)]
    Ui(#[from] UiValidationError),

    #[error("failed to expand `data_dir`: {0}")]
    DataDir(shellexpand::LookupError<std::env::VarError>),

View on GitHub (pinned to 900007c480)