crossbeam-rs/crossbeam · error

no operations have been added to `Select`

Error message

no operations have been added to `Select`

What it means

crossbeam-channel's `select!`/internal `select` function panics when the slice of channel operation handles is empty. The select mechanism needs at least one channel operation to wait on; with zero handles there is nothing to select from, so the library treats it as a programmer error and panics rather than returning a result.

Solutions

  1. Register at least one operation with `Select::recv()` or `Select::send()` before calling `select()`
  2. Check `select_instance.handles`-style emptiness (or track registered count yourself) and return early or block on a different mechanism when zero operations exist
  3. If operations are conditional, ensure a default/fallback operation (e.g. a never channel or a timeout case) is always registered

Example fix

// before
let mut sel = Select::new();
if cond { sel.recv(&rx1); }
let oper = sel.select(); // panics if !cond

// after
let mut sel = Select::new();
sel.recv(&rx1); // always register at least one op
if cond { sel.recv(&rx2); }
let oper = sel.select();
Defensive patterns

Strategy: validation

Validate before calling

if sel_operations_registered == 0 {
    // skip select, fall back to waiting
    return;
}

Prevention

When it happens

Trigger: Calling `crossbeam_channel::Select::select()` (or `select_timeout()`, or the internal `select()` helper) on a `Select` instance into which no operations were registered via `recv`/`send`, or after the handle slice was drained/emptied.

Common situations: Building a `Select` dynamically in a loop where an early branch skips all `recv`/`send` registration calls; conditionally adding operations where all conditions are false; refactoring code that removed the registration but left the `select()` call in place.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of crossbeam-rs/crossbeam@38dacb4622 (2026-09-13). Data as JSON: /api/errors/664965940d569d10. Report an issue: GitHub.

Appendix: source

Thrown at crossbeam-channel/src/select.rs:479

        None => Err(TrySelectError),
        Some((token, index, addr)) => Ok(SelectedOperation {
            token,
            index,
            addr,
            _marker: PhantomData,
        }),
    }
}

/// Blocks until one of the operations becomes ready and selects it.
// This is a private API (exposed inside crossbeam_channel::internal module) that is used by the select macro.
#[inline]
pub fn select<'a>(
    handles: &mut [(&'a dyn SelectHandle, usize, usize)],
    is_biased: bool,
) -> SelectedOperation<'a> {
    if handles.is_empty() {
        panic!("no operations have been added to `Select`");
    }

    let (token, index, addr) = run_select(handles, Timeout::Never, is_biased).unwrap();
    SelectedOperation {
        token,
        index,
        addr,
        _marker: PhantomData,
    }
}

/// Blocks for a limited time until one of the operations becomes ready and selects it.
// This is a private API (exposed inside crossbeam_channel::internal module) that is used by the select macro.
#[inline]
pub fn select_timeout<'a>(
    handles: &mut [(&'a dyn SelectHandle, usize, usize)],
    timeout: Duration,
    is_biased: bool,

View on GitHub (pinned to 38dacb4622)