aaif-goose/goose · error

Range contains {cell_count} cells; maximum is {MAX_RANGE_CEL

Error message

Range contains {cell_count} cells; maximum is {MAX_RANGE_CELLS}

What it means

validate_range_bounds() computes the range area as row_count * column_count (with checked arithmetic) and enforces MAX_RANGE_CELLS = 100_000 (xlsx_tool.rs:8). Larger ranges bail with the actual cell count and the limit. This is a resource guard: reading a huge range would build a massive Vec of cell values in memory.

Source

Thrown at crates/goose-mcp/src/computercontroller/xlsx_tool.rs:256

        "Column must be between 1 and {MAX_EXCEL_COLUMNS}"
    );
    anyhow::ensure!(
        start_row <= end_row && start_col <= end_col,
        "Range start must not follow range end"
    );

    let row_count = end_row
        .checked_sub(start_row)
        .and_then(|span| span.checked_add(1))
        .context("Row span overflow")?;
    let column_count = end_col
        .checked_sub(start_col)
        .and_then(|span| span.checked_add(1))
        .context("Column span overflow")?;
    let cell_count = u64::from(row_count)
        .checked_mul(u64::from(column_count))
        .context("Range area overflow")?;
    anyhow::ensure!(
        cell_count <= MAX_RANGE_CELLS,
        "Range contains {cell_count} cells; maximum is {MAX_RANGE_CELLS}"
    );

    Ok((row_count, column_count))
}

fn parse_cell_reference(reference: &str) -> Result<(u32, u32)> {
    // Parse Excel cell reference (e.g., "A1") and return (row, column) to match umya_spreadsheet's expectation
    let mut col_str = String::new();
    let mut row_str = String::new();
    let mut parsing_row = false;

    for c in reference.chars() {
        if c.is_alphabetic() {
            if parsing_row {
                anyhow::bail!("Invalid cell reference format");
            }

View on GitHub (pinned to 3810898a74)

Solutions

  1. Shrink the range to at most 100_000 cells (e.g. 'A1:Z2000' is 52_000).
  2. Page through data in chunks: iterate row windows of a few thousand rows.
  3. Use the worksheet dimensions (highest_row/highest_column) to bound the range to the actually used area.
  4. For exports, prefer file-level operations over reading every cell.

Example fix

// before
let range = "A1:XFD1048576"; // ~17 billion cells -> 'Range contains ... cells; maximum is 100000'

// after
let range = "A1:Z2000"; // 52_000 cells, within the 100_000 limit
Defensive patterns

Strategy: validation

Validate before calling

const MAX_RANGE_CELLS: u64 = 100_000;
fn cell_count(sr: u32, sc: u32, er: u32, ec: u32) -> u64 {
    u64::from(er - sr + 1) * u64::from(ec - sc + 1)
}
if cell_count(sr, sc, er, ec) > MAX_RANGE_CELLS {
    // clamp rows so area fits the budget, e.g. full-width reads:
    let cols = ec - sc + 1;
    let max_rows = (MAX_RANGE_CELLS / u64::from(cols)) as u32;
    er = (er.min(sr + max_rows - 1));
}
let range = format!("{}{}:{}{}", col_name(sc), sr, col_name(ec), er);

Prevention

When it happens

Trigger: Ranges like 'A1:XFD1048576' (full sheet, ~17.2B cells), 'A1:Z100000' (2.6M cells), or 'A1:A100001' (100_001 cells, one over). Even if the worksheet is mostly empty, the REQUESTED rectangle is what is counted.

Common situations: Agents requesting 'all data' as a full-sheet range; whole-column reads ('A:A' style translated to max rows); users expecting the tool to return megabyte-scale exports in one call.

Related errors


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/679a999d8d7835fd. Report an issue: GitHub.