zed-industries/zed · error

{self:?} is not a toggle action

Error message

{self:?} is not a toggle action

What it means

SearchOption::to_toggle_action() returns the toggle Action for the four options that have one (ToggleWholeWord, ToggleCaseSensitive, ToggleIncludeIgnored, ToggleRegex); as_button() calls it unconditionally on its first line (crates/search/src/search.rs:135). Variants without a toggle action — OneMatchPerLine, Backwards — hit the panic arm at crates/search/src/search.rs:125.

Source

Thrown at crates/search/src/search.rs:125

    }

    pub fn icon(&self) -> ui::IconName {
        match self {
            SearchOption::WholeWord => IconName::WholeWord,
            SearchOption::CaseSensitive => IconName::CaseSensitive,
            SearchOption::IncludeIgnored => IconName::FileIgnored,
            SearchOption::Regex => IconName::Regex,
            _ => panic!("{self:?} is not a named SearchOption"),
        }
    }

    pub fn to_toggle_action(self) -> &'static dyn Action {
        match self {
            SearchOption::WholeWord => &ToggleWholeWord,
            SearchOption::CaseSensitive => &ToggleCaseSensitive,
            SearchOption::IncludeIgnored => &ToggleIncludeIgnored,
            SearchOption::Regex => &ToggleRegex,
            _ => panic!("{self:?} is not a toggle action"),
        }
    }

    pub fn as_button(
        &self,
        active: SearchOptions,
        search_source: SearchSource,
        focus_handle: FocusHandle,
    ) -> impl IntoElement {
        let action = self.to_toggle_action();
        let label = self.label();

        IconButton::new(
            (label, matches!(search_source, SearchSource::Buffer) as u32),
            self.icon(),
        )
        .map(|button| match search_source {
            SearchSource::Buffer => {

View on GitHub (pinned to f4178619ac)

Solutions

  1. Filter to the four toggle options before building buttons (a matches! guard or a const list next to the enum).
  2. If the variant needs a toggle action, define the Action and add a match arm to to_toggle_action().
  3. Make the match exhaustive to turn future variant additions into compile errors.
  4. Check the backtrace: the caller above as_button passed the unsupported variant.

Example fix

// before
for option in all_options { // includes OneMatchPerLine, Backwards
    toolbar.child(option.as_button(active, source, focus.clone()));
}

// after
const TOGGLE_OPTIONS: &[SearchOption] = &[
    SearchOption::WholeWord,
    SearchOption::CaseSensitive,
    SearchOption::IncludeIgnored,
    SearchOption::Regex,
];
for option in TOGGLE_OPTIONS {
    toolbar.child(option.as_button(active, source, focus.clone()));
}
Defensive patterns

Strategy: type-guard

Type guard

fn has_toggle_action(option: SearchOption) -> bool {
    matches!(
        option,
        SearchOption::WholeWord
            | SearchOption::CaseSensitive
            | SearchOption::IncludeIgnored
            | SearchOption::Regex
    )
}

if has_toggle_action(option) {
    let action = option.to_toggle_action(); // safe: only the four toggle variants
}

Prevention

When it happens

Trigger: Calling SearchOption::to_toggle_action() or SearchOption::as_button() with SearchOption::OneMatchPerLine or SearchOption::Backwards; any generic loop that builds a button per option without filtering to the toggle subset.

Common situations: Data-driven option rendering that assumes every option is a toolbar toggle; newly added SearchOption variants not classified; UI refactors generalizing the search options bar.

Related errors


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/257bbd904cc42996. Report an issue: GitHub.