Hmbown/CodeWhale · info · anyhow::Error

Selection out of range

Error message

Selection out of range

What it means

The interactive session picker maps the entered 1-based number to the list via sessions.get(idx.saturating_sub(1)). If the number exceeds the list length, the lookup fails with 'Selection out of range'. Note the saturating_sub quirk: entering 0 wraps to index 0 and silently selects the first session instead of erroring.

Source

Thrown at crates/tui/src/lib.rs:7816

    println!("Select a session to resume:");
    for (idx, session) in sessions.iter().enumerate() {
        println!("  {:>2}. {} ({})", idx + 1, session.title, session.id);
    }
    print!("Enter a number (or press Enter to cancel): ");
    io::stdout().flush()?;

    let mut input = String::new();
    io::stdin().read_line(&mut input)?;
    let input = input.trim();
    if input.is_empty() {
        bail!("No session selected.");
    }
    let idx: usize = input
        .parse()
        .map_err(|_| anyhow::anyhow!("Invalid input"))?;
    let session = sessions
        .get(idx.saturating_sub(1))
        .ok_or_else(|| anyhow::anyhow!("Selection out of range"))?;
    Ok(session.id.clone())
}

async fn run_review(config: &Config, args: ReviewArgs) -> Result<()> {
    use crate::client::DeepSeekClient;

    let diff = collect_diff(&args)?;
    if diff.trim().is_empty() {
        bail!("No diff to review.");
    }
    validate_review_receipt_args(&args)?;
    if args.check_receipt {
        return run_review_receipt_check(&diff, &args);
    }

    let model = resolve_review_model(config, args.model.as_deref());
    let route = resolve_cli_exec_route(config, &model, &diff, args.model.is_none()).await?;
    let execution_config = config_for_cli_route(config, &route);

View on GitHub (pinned to 8880682c63)

Solutions

  1. Re-check the printed list and enter a number between 1 and the number of sessions
  2. Clear the screen or scrollback and re-run so the current list is visible
  3. In scripts, resume by explicit session ID instead of a positional pick
  4. If you entered 0, be aware it opened the first session — verify which session you are in
Defensive patterns

Strategy: validation

Validate before calling

let n = sessions.len();
match input.trim().parse::<usize>() {
    Ok(i) if (1..=n).contains(&i) => { /* safe to select */ }
    _ => eprintln!("enter a number from 1 to {n}"),
}

Type guard

fn selection_in_range(input: &str, len: usize) -> bool {
    matches!(input.trim().parse::<usize>(), Ok(i) if (1..=len).contains(&i))
}

Prevention

When it happens

Trigger: Entering a number larger than the count of listed sessions (for example 7 when 3 are shown); the list shrank between display and input; reading a stale longer list from scrollback. Entering 0 does not error — it selects the first session.

Common situations: The terminal shows a longer list from an earlier run in scrollback; a typo adds a digit; a script pipes a fixed index that outlived the session count.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/b6abef83454bf297. Report an issue: GitHub.