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
- Register at least one operation with `Select::recv()` or `Select::send()` before calling `select()`
- Check `select_instance.handles`-style emptiness (or track registered count yourself) and return early or block on a different mechanism when zero operations exist
- 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
- Always register at least one recv/send before select()
- Track registration count when building Select dynamically
- Prefer the select! macro which encodes at least one branch statically
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
- dropped `SelectedOperation` without completing the operation
- bounded channel capacity is too large
- queue capacity is too large
- failed to spawn scoped thread
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)