iOfficeAI/OfficeCLI · error · System.InvalidOperationException

Workbook not found

Error message

Workbook not found

What it means

Thrown by AddRun when _doc.WorkbookPart is null. This is an InvalidOperationException (not ArgumentException) because it indicates the loaded SpreadsheetDocument has no workbook part rather than a bad argument. In practice this means the document was opened in a mode or state where the workbook part is absent or could not be resolved.

Source

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

    }

    private string AddRun(string parentPath, string type, InsertPosition? position, Dictionary<string, string> properties)
    {
        var index = position?.Index;
        // Add a rich text run to a cell: parentPath = /SheetName/CellRef
        var runSegments = parentPath.TrimStart('/').Split('/', 2);
        if (runSegments.Length < 2)
            throw new ArgumentException("Parent path must be /SheetName/CellRef for adding a run");
        var runSheetName = runSegments[0];
        var runCellRef = runSegments[1].ToUpperInvariant();
        var runWorksheet = FindWorksheet(runSheetName)
            ?? throw new ArgumentException($"Sheet not found: {runSheetName}");
        var runSheetData = GetSheet(runWorksheet).GetFirstChild<SheetData>()
            ?? GetSheet(runWorksheet).AppendChild(new SheetData());
        var runCell = FindOrCreateCell(runSheetData, runCellRef);

        var runWbPart = _doc.WorkbookPart
            ?? throw new InvalidOperationException("Workbook not found");
        var runSstPart = runWbPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault()
            ?? runWbPart.AddNewPart<SharedStringTablePart>();
        SharedStringTable runSst;
        if (runSstPart.SharedStringTable != null)
            runSst = runSstPart.SharedStringTable;
        else
        {
            runSst = new SharedStringTable();
            runSstPart.SharedStringTable = runSst;
        }

        SharedStringItem? runSsi = null;
        if (runCell.DataType?.Value == CellValues.SharedString &&
            int.TryParse(runCell.CellValue?.Text, out var existingSstIdx))
        {
            runSsi = runSst.Elements<SharedStringItem>().ElementAtOrDefault(existingSstIdx);
        }
        if (runSsi == null)

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Re-open the document from a known-good .xlsx copy and retry.
  2. Validate the package before editing: check that the workbook part exists (e.g. via the library's open/validate path).
  3. If the file is a template, save a normal .xlsx copy first and operate on that.
Defensive patterns

Strategy: try-catch

Try / catch

try { handler.Add(parentPath, "run", pos, props); }
catch (InvalidOperationException ex) when (ex.Message == "Workbook not found")
{ /* file is corrupt; re-open from a known-good copy or abort */ }

Prevention

When it happens

Trigger: The handler was constructed on a document that is not a valid .xlsx (e.g. a flat OPC part stream, a template lacking workbook.xml, or a document opened AutoSave/readonly on a corrupted file). Reachable only after the sheet and cell were found, so a corrupt-but-loadable file can get this far.

Common situations: Operating on a .xltm/.xltx template whose workbook part is structured differently. A file that was truncated or partially written. Opening a non-Excel OPC package that the SDK tolerates on load.

Related errors


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