iOfficeAI/OfficeCLI · error · ArgumentException

Sheet not found: {sheetName}

Error message

Sheet not found: {sheetName}

What it means

Thrown by ExcelHandler.Move at the very first step: FindWorksheet(sheetName) returned null, meaning the first segment of sourcePath does not name any worksheet in the workbook. The handler splits sourcePath on '/' and treats segment[0] as the sheet, so a missing sheet fails before any move logic runs. It is the standard 'you asked to move from a sheet that does not exist' guard.

Source

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

            case "cfextended":
                return AddCfExtended(parentPath, type, position, properties);

            case "sparkline":
                return AddSparkline(parentPath, type, position, properties);

            default:
                return AddDefault(parentPath, type, position, properties);
        }
    }

    public string Move(string sourcePath, string? targetParentPath, InsertPosition? position, Dictionary<string, string>? properties = null)
    {
        // xlsx has no track-change concept; `properties` is accepted for IDocumentHandler parity but ignored.
        var index = position?.Index;
        var segments = sourcePath.TrimStart('/').Split('/', 2);
        var sheetName = segments[0];
        var worksheet = FindWorksheet(sheetName)
            ?? throw new ArgumentException($"Sheet not found: {sheetName}");

        if (segments.Length < 2)
        {
            // Move (reorder) the sheet within the workbook.
            // CONSISTENCY(move-anchor): mirrors PowerPointHandler.Move slide reorder —
            // supports --index / --after /Sheet2 / --before /Sheet3.
            var workbook = GetWorkbook();
            var sheets = workbook.GetFirstChild<Sheets>()
                ?? throw new InvalidOperationException("Workbook has no sheets element");
            var sheetEl = sheets.Elements<Sheet>().FirstOrDefault(s =>
                string.Equals(s.Name?.Value, sheetName, StringComparison.OrdinalIgnoreCase))
                ?? throw new ArgumentException($"Sheet not found: {sheetName}");

            // Resolve after/before anchor BEFORE removing sheetEl.
            static string ExtractAnchorSheetName(string raw) =>
                (raw.StartsWith("/") ? raw[1..] : raw).Split('/', 2)[0];

            Sheet? afterAnchor = null, beforeAnchor = null;

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Enumerate sheets first (handler.Get("/", depth:1) or the dump) and confirm the exact name before calling Move.
  2. Trim and verify the first segment of sourcePath is non-empty and matches an existing sheet.
  3. If the sheet was deleted/renamed, refresh the path from the current workbook.

Example fix

// before
h.Move("/Dat/row[2]", "/Report", InsertPosition.AtIndex(0)); // typo: 'Dat'
// after
var sheet = h.Get("/", depth:1).Children.First(c => c.Name.Equals("Data", StringComparison.OrdinalIgnoreCase));
h.Move($"/{sheet.Name}/row[2]", "/Report", InsertPosition.AtIndex(0));
Defensive patterns

Strategy: validation

Validate before calling

// Resolve the sheet segment exactly as Move does, then confirm it exists.
var firstSeg = sourcePath.AsSpan().TrimStart('/').ToString().Split('/', 2)[0];
var sheets = handler.Get("/", depth: 1).Children
    .Select(c => c.Name).ToList();
if (!sheets.Any(s => s.Equals(firstSeg, StringComparison.OrdinalIgnoreCase)))
    throw new InvalidOperationException($"Refusing Move: sheet '{firstSeg}' not in {string.Join(", ", sheets)}");

Type guard

static bool IsSheetPath(string path) =>
    !string.IsNullOrWhiteSpace(path)
    && path.TrimStart('/').Split('/', 2)[0].Length > 0;

Try / catch

try { handler.Move(sourcePath, target, pos); }
catch (ArgumentException ex) when (ex.Message.StartsWith("Sheet not found"))
{ /* surface as a user-facing 'no such sheet' message; list available sheets */ }

Prevention

When it happens

Trigger: Calling Move("/Misnamed/row[3]") where 'Misnamed' is not a worksheet; a leading slash/whitespace mismatch; calling Move on a path whose first segment is empty (e.g. sourcePath = "/"). Case-insensitive lookup is used for the later <sheets> catalog, but this first lookup still misses when the name is genuinely absent.

Common situations: Sheet renamed between sessions; copy-paste path with a stale sheet name; trailing spaces in the name; referencing a chart/dialog sheet that is not enumerated as a worksheet; operating on the wrong workbook instance.

Related errors


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