iOfficeAI/OfficeCLI · critical · System.InvalidOperationException
Workbook not found
Error message
Workbook not found
What it means
Thrown by AddFormulaCf when _doc.WorkbookPart is null while trying to attach the DifferentialFormat (dxf) to the stylesheet. WorkbookPart being null indicates the SpreadsheetDocument is in a state where no workbook part is loaded — typically a corrupt, empty, or incorrectly-opened package. This is an InvalidOperationException (internal-state failure), not an ArgumentException (user input).
Source
Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Cf.cs:472
// Build DifferentialFormat (dxf) for the formatting.
// A dxf Font may carry: b, i, u, strike, sz, rFont, color.
// All sub-props are threaded together so users can combine
// (e.g. bold + italic + underline + custom size + name).
var dxf = new DifferentialFormat();
var dxfFont = BuildFormulaCfFont(properties);
if (dxfFont != null) dxf.Append(dxfFont);
if (properties.TryGetValue("fill", out var fillColor))
{
var normalizedFillColor = ParseHelpers.NormalizeArgbColor(fillColor);
dxf.Append(new Fill(new PatternFill(
new BackgroundColor { Rgb = normalizedFillColor })
{ PatternType = PatternValues.Solid }));
}
// Add dxf to stylesheet (ensure it exists)
var fcfWbPart = _doc.WorkbookPart
?? throw new InvalidOperationException("Workbook not found");
var fcfStyleMgr = new ExcelStyleManager(fcfWbPart);
fcfStyleMgr.EnsureStylesPart();
var stylesheet = fcfWbPart.WorkbookStylesPart!.Stylesheet!;
var dxfs = stylesheet.GetFirstChild<DifferentialFormats>();
if (dxfs == null)
{
dxfs = new DifferentialFormats { Count = 0 };
stylesheet.Append(dxfs);
}
dxfs.Append(dxf);
dxfs.Count = (uint)dxfs.Elements<DifferentialFormat>().Count();
_dirtyStylesheet = true;
var dxfId = dxfs.Count!.Value - 1;
var fcfRule = new ConditionalFormattingRule
{View on GitHub (pinned to 1ced45e900)
Solutions
- Open a valid .xlsx file that contains a workbook part; verify integrity before calling Add.
- If the document was created programmatically, ensure the WorkbookPart was added (e.g. SpreadsheetDocument.Create with WorkbookPart) before invoking the handler.
- Re-open the source file from a known-good copy.
Defensive patterns
Strategy: try-catch
Validate before calling
if (_doc.WorkbookPart is null)
throw new InvalidOperationException("Cannot add CF: document has no WorkbookPart. Open a valid .xlsx."); Type guard
static bool HasWorkbookPart(SpreadsheetDocument doc) => doc.WorkbookPart is not null;
Try / catch
try { return Add(path, "formulacf", pos, props); }
catch (InvalidOperationException ex) when (ex.Message == "Workbook not found")
{ /* reload document from known-good source, then retry once */ throw; } Prevention
- Validate the source .xlsx opens with a non-null WorkbookPart before any Add.
- Do not wrap non-spreadsheet streams in the Excel handler.
- For programmatically-created packages, add the WorkbookPart before handler use.
When it happens
Trigger: Calling Add formula CF on a SpreadsheetDocument whose WorkbookPart is null. This happens when the document was opened from a non-xlsx stream, a template missing the workbook part, or after a prior mutation corrupted the package in memory.
Common situations: Opening a .xltm/.xltx template whose root part differs; loading a partial/corrupt file; a programmatic caller constructing ExcelHandler around a freshly-created but uninitialized package.
Related errors
- Sheet not found: {fcfSheetName}
- Formula-based conditional formatting requires 'formula' prop
- Worksheet missing
- Workbook is missing
- pivotCacheDefinition is missing <cacheFields>
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/361b08683c056075.
Report an issue: GitHub.