iOfficeAI/OfficeCLI · error · ArgumentException

Sheet not found

Error message

Sheet not found: {shpSheetName}

What it means

Thrown by AddShape when the first segment of the parent path (the sheet name) does not match any worksheet in the workbook. FindWorksheet does a case-insensitive lookup against GetWorksheets() and returns null, which the null-coalescing ?? operator converts into this ArgumentException. It is a pure input-validation failure: no file mutation happens before the throw. The same guard exists on the sparkline path (error 545) and most other drawing add handlers.

Solutions

  1. List the actual sheets with the tool's sheet-listing command and copy the exact name (FindWorksheet is case-insensitive, but trailing spaces and exact spelling matter).
  2. Correct the leading path segment to match an existing sheet, e.g. `/Sheet1` instead of `/SheetX`.
  3. If scripting, resolve the sheet name dynamically from the workbook before building the path instead of hard-coding it.

Example fix

// before
add ./book.xlsx /SalesData shape --type rectangle --anchor B2:F7
// after
add ./book.xlsx /Sheet1 shape --type rectangle --anchor B2:F7
Defensive patterns

Strategy: validation

Validate before calling

// Resolve the sheet against the workbook before building the path.
// FindWorksheet is case-insensitive; mirror that here.
var sheets = GetWorksheetNames(workbook); // your enumeration
if (!sheets.Any(s => s.Equals(sheetName, StringComparison.OrdinalIgnoreCase)))
    throw new InvalidOperationException(
        $"Sheet '{sheetName}' not found. Available: {string.Join(", ", sheets)}");

Type guard

static bool SheetExists(WorkbookPart wbp, string sheetName)
    => wbp.Workbook.Sheets.Elements<Sheet>()
        .Any(s => s.Name.Value.Equals(sheetName, StringComparison.OrdinalIgnoreCase));

Try / catch

try { handler.Add(...); }
catch (ArgumentException ex) when (ex.Message.StartsWith("Sheet not found"))
{
    // re-resolve sheet list, surface to user, do not retry blindly
    Console.Error.WriteLine(ex.Message);
}

Prevention

When it happens

Trigger: Calling the `add` command with a shape/table type and a parent path whose leading segment names a non-existent sheet, e.g. `add /SheetX shape ...` when the workbook only contains `Sheet1`. Also fires when the sheet was renamed, the wrong file was opened, or the path is malformed (empty leading segment).

Common situations: Typos or casing/whitespace in the sheet name on the command line; sheet renamed between sessions; script operating on a template that has a different sheet layout; copied command from another workbook without adjusting the sheet name.

Related errors


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

Appendix: source

Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Drawings.cs:576

        // DEFERRED(xlsx/picture-anchor-mode) P12: enumerate all anchor
        // kinds (twoCell / oneCell / absolute) when counting picture slots.
        var picAnchors = picDrawingsPart.WorksheetDrawing
            .Elements<OpenXmlElement>()
            .Where(a => (a is XDR.TwoCellAnchor || a is XDR.OneCellAnchor || a is XDR.AbsoluteAnchor)
                && a.Descendants<XDR.Picture>().Any())
            .ToList();
        var picIdx = PathIndex.FromArrayIndex(picAnchors.IndexOf(anchor));

        return $"/{picSheetName}/picture[{picIdx}]";
    }

    private string AddShape(string parentPath, string type, InsertPosition? position, Dictionary<string, string> properties)
    {
        var index = position?.Index;
        var shpSegments = parentPath.TrimStart('/').Split('/', 2);
        var shpSheetName = shpSegments[0];
        var shpWorksheet = FindWorksheet(shpSheetName)
            ?? throw new ArgumentException($"Sheet not found: {shpSheetName}");

        // CONSISTENCY(ole-width-units): accept `anchor=B2:F7` as a cell
        // range (same grammar as OLE's anchor=), alongside the legacy
        // x/y/width/height (column/row units) form. When both are
        // supplied, warn and let anchor= win — it defines the full
        // rectangle, so width/height are ambiguous.
        // CONSISTENCY(ref-alias): `ref=<cell>` maps to single-cell
        // anchor `<cell>:<cell>`, matching cell/comment/table which
        // accept `ref=` as the placement address. Explicit `anchor=`
        // wins if both are given.
        if (!properties.ContainsKey("anchor")
            && properties.TryGetValue("ref", out var shpRefProp)
            && !string.IsNullOrWhiteSpace(shpRefProp))
        {
            var refTrim = shpRefProp.Trim();
            if (!refTrim.Contains(':'))
            {
                // Single-cell ref (e.g. "B2"): expand to a 1x1 cell

View on GitHub (pinned to 1ced45e900)