iOfficeAI/OfficeCLI · error · ArgumentException

Sheet not found: {catSheetName}

Error message

Sheet not found: {catSheetName}

What it means

Same sheet resolution as error 671 but for the categories sheet prefix. After splitting '!' off the categories ref, FindWorksheet(catSheetName) returns null and throws the terse 'Sheet not found'. Same case-insensitive name + sheet[N]/sheet[last] alias resolution.

Source

Thrown at src/officecli/Handlers/Excel/ExcelHandler.Helpers.Chart.cs:662

        if (bangIdx >= 0)
        {
            catSheetName = rangePart[..bangIdx].Trim('\'');
            rangePart = rangePart[(bangIdx + 1)..];
        }

        var cleanRange = rangePart.Replace("$", "");
        var rangeParts = cleanRange.Split(':');
        if (rangeParts.Length != 2)
            throw new ArgumentException(
                $"Invalid categories range: '{explicitValue}'. Expected format: 'Sheet1!A2:A3' or 'A2:A3'.");

        var (startCol, startRow) = ParseCellReference(rangeParts[0]);
        var (endCol, endRow) = ParseCellReference(rangeParts[1]);
        var startColIdx = ColumnNameToIndex(startCol);
        var endColIdx = ColumnNameToIndex(endCol);

        var ws = FindWorksheet(catSheetName)
            ?? throw new ArgumentException($"Sheet not found: {catSheetName}");
        var sheetData = GetSheet(ws).GetFirstChild<SheetData>()
            ?? throw new ArgumentException($"Sheet '{catSheetName}' has no data");

        // Read the explicit-range cells directly (rows may differ from dataRange).
        var lookup = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
        foreach (var row in sheetData.Elements<Row>())
        {
            var rowIdx = (int)(row.RowIndex?.Value ?? 0);
            if (rowIdx < startRow || rowIdx > endRow) continue;
            foreach (var cell in row.Elements<Cell>())
                if (cell.CellReference?.Value != null)
                    lookup[cell.CellReference.Value] = GetCellDisplayValue(cell);
        }

        var labels = new List<string>();
        for (int r = startRow; r <= endRow; r++)
            for (int c = startColIdx; c <= endColIdx; c++)
            {

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Verify the sheet exists (GetDumpSheetNames) before charting.
  2. Use a positional alias sheet[N] if you only know the index.
  3. Drop the explicit categories to fall back to defaults.
  4. Re-author the categories ref against the current sheet name.

Example fix

// before
props["categories"] = "OldCats!A2:A10";  // sheet renamed -> throw

// after
props["categories"] = "Labels!A2:A10";  // current name
Defensive patterns

Strategy: validation

Validate before calling

var sheet = cats.Contains('!') ? cats[..cats.IndexOf('!')].Trim('\'') : defaultSheet;
if (!handler.GetDumpSheetNames().Contains(sheet, StringComparer.OrdinalIgnoreCase))
    throw new ArgumentException($"categories sheet '{sheet}' does not exist");

Prevention

When it happens

Trigger: categories=RenamedSheet!A2:A3; a categories ref whose sheet prefix was renamed or deleted.

Common situations: Categories sheet renamed after authoring; sheet deleted; typo in the prefix.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/8a35e69fcc84a5d8. Report an issue: GitHub.