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
- Re-open the document from a known-good .xlsx copy and retry.
- Validate the package before editing: check that the workbook part exists (e.g. via the library's open/validate path).
- 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
- Run the library's validate/open check on the file before editing.
- Keep a pristine backup copy and re-open from it when a workbook-part error appears.
- Avoid editing templates in place; save a normal .xlsx first.
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
- Worksheet missing
- Workbook is missing
- pivotCacheDefinition is missing <cacheFields>
- pivotTableDefinition is missing <pivotFields>
- Parent path must be /SheetName/CellRef for adding a run
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/622e70282e26da4d.
Report an issue: GitHub.