atuinsh/atuin · info

the vector is not empty

Error message

the vector is not empty

What it means

Panic inside a LazyLock static initializer: OrFilter::from_list is called with the hardcoded one-element vec![AuthorPattern::AllUser] and is expected to succeed because from_list rejects empty lists. Since the vector is a compile-time constant with one element, the Err branch is unreachable; this expect documents the invariant, it cannot be tripped by any caller or input.

Source

Thrown at crates/atuin-client/src/history.rs:73

    }
}

impl From<&str> for AuthorPattern {
    fn from(value: &str) -> Self {
        match value {
            AUTHOR_FILTER_ALL_USER => Self::AllUser,
            AUTHOR_FILTER_ALL_AGENT => Self::AllAgent,
            _ => Self::Name(value.to_owned()),
        }
    }
}

/// An author filter that only allows non-agent commands (i.e., [`AuthorPattern::AllUser`]).
///
/// This function uses a [`LazyLock`] to avoid building the filter every time.
pub fn all_user_author_filter() -> OrFilter<&'static [AuthorPattern]> {
    static FILTER: LazyLock<OrFilter<Vec<AuthorPattern>>> = LazyLock::new(|| {
        OrFilter::from_list(vec![AuthorPattern::AllUser]).expect("the vector is not empty")
    });
    FILTER.as_slice_filter()
}

const HISTORY_AUTHOR_ENV: &str = "ATUIN_HISTORY_AUTHOR";
const HISTORY_INTENT_ENV: &str = "ATUIN_HISTORY_INTENT";

#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, derive_more::Display)]
#[display("{}", self.name())]
#[repr(u16)]
pub enum Version {
    Zero = 0,
    One = 1,
    Two = 2,
}

impl Version {
    pub const VARIANTS: [Self; 3] = [Self::Zero, Self::One, Self::Two];

View on GitHub (pinned to 15fe1318f1)

Solutions

  1. Recognize this as an internal invariant: no runtime or config change can trigger it, so a crash here means the filter code was modified
  2. If you refactored from_list, re-read its contract: it rejects only empty lists, so ensure one-element lists and AllUser still pass
  3. Keep the vec literal non-empty when editing; if the filter set ever becomes configurable, replace the expect with real error propagation
Defensive patterns

Strategy: validation

Validate before calling

// When building your own OrFilters, check the list before construction:
fn or_filter_or_default(list: Vec<AuthorPattern>) -> OrFilter<Vec<AuthorPattern>> {
    if list.is_empty() {
        OrFilter::from_list(vec![AuthorPattern::AllUser]).expect("fallback vector is not empty")
    } else {
        OrFilter::from_list(list).expect("checked non-empty")
    }
}

Type guard

fn is_non_empty_filter_list(list: &[AuthorPattern]) -> bool {
    !list.is_empty()
}

Prevention

When it happens

Trigger: First call to all_user_author_filter() (history filtering that excludes agent-authored commands) would panic only if from_list additionally rejected single-element or specifically AllUser-only lists — behavior that does not exist in the shipped filter implementation. Because LazyLock re-runs an initializer that panicked, a hypothetical failure would repeat on every call rather than poison once.

Common situations: None in practice. A developer refactoring AuthorPattern or OrFilter::from_list semantics (e.g., changing the empty-list rule or adding new rejection cases) could accidentally make this invariant false — the panic then fires on the first history query after startup.

Related errors


AI-assisted analysis of atuinsh/atuin@15fe1318f1 (2026-08-19). Data as JSON: /api/errors/2edd2075cf55cfd0. Report an issue: GitHub.