iOfficeAI/OfficeCLI · error · InvalidOperationException
Workbook is missing
Error message
Workbook is missing
What it means
Thrown by CreatePivotTable when workbookPart.Workbook is null — the package's root Workbook element is missing. This is a structural integrity failure: a valid OOXML package always has a <workbook> element as the root of workbook.xml. Without it, no pivot table can be registered because the cache-id allocation and <pivotCaches> collection both live under Workbook.
Source
Thrown at src/officecli/Core/PivotTableHelper.cs:1067
// the full source on every Refresh.
var labelFilterSpec = ParseLabelFilterSpec(headers, properties);
// 2b. Apply Top-N filter to the source rows (ranked by the first value
// field's aggregate on the outermost row field). Runs BEFORE cache
// build so the cache, rendered cells, and grand totals all reflect
// the filtered subset. See ApplyTopNFilter for semantics & limits.
if ((properties.TryGetValue("topN", out var topNStr)
|| properties.TryGetValue("topn", out topNStr))
&& int.TryParse(topNStr, System.Globalization.NumberStyles.Integer,
System.Globalization.CultureInfo.InvariantCulture, out var topN))
{
ApplyTopNFilter(columnData, rowFields, valueFields, topN);
}
// 3. Generate unique cache ID
uint cacheId = 0;
var workbook = workbookPart.Workbook
?? throw new InvalidOperationException("Workbook is missing");
var pivotCaches = workbook.GetFirstChild<PivotCaches>();
if (pivotCaches != null)
cacheId = pivotCaches.Elements<PivotCache>().Select(pc => pc.CacheId?.Value ?? 0u).DefaultIfEmpty(0u).Max() + 1;
// Design change (cache sharing): if any existing pivot already binds
// to an equivalent (sheet, range) source, reuse its
// PivotTableCacheDefinitionPart instead of creating a new one. This
// matches Excel's "one cache per source" contract — refresh
// propagates across siblings, file size doesn't blow up. See
// CountCacheReferrers / FindMatchingCachePart in
// PivotTableHelper.Cache.cs for the supporting helpers.
// Date-grouped pivots add derived cacheFields (year/quarter/month/...)
// with <fieldGroup> XML. Calculated-field pivots append synthetic
// cacheFields with formula= attributes. Both mutate the cache schema
// in ways the sibling pivots don't expect — pivotFields.count on
// siblings stays at the original column count while cacheFields.count
// grows, and Excel rejects the workbook on that mismatch.
// Force a fresh cache when this pivot has either, so its schemaView on GitHub (pinned to 1ced45e900)
Solutions
- Open and re-save the workbook in Excel or LibreOffice to rebuild the package structure.
- If creating the workbook programmatically, ensure the Workbook part is properly initialized before adding pivots.
- Verify the file is a valid xlsx (not a renamed xls, csv, or zip).
- Start from a known-good workbook template.
Defensive patterns
Strategy: try-catch
Try / catch
try { CreatePivotTable(workbookPart, sourceSheet, sourceRef, props); }
catch (InvalidOperationException ex) when (ex.Message == "Workbook is missing")
{
// The package is structurally corrupt — workbook.xml is absent.
// Re-save in Excel/LibreOffice, or start from a valid template.
throw new InvalidOperationException($"'{path}' has no Workbook element. Re-save or repair the file.", ex);
} Prevention
- Use known-good workbook templates as starting points.
- Verify the file is a valid xlsx (check the zip structure and workbook.xml presence).
- Do not process files from untrusted sources without validation.
- If generating packages programmatically, ensure the Workbook part is created before adding pivots.
When it happens
Trigger: Creating a pivot in a workbook whose workbook.xml is missing or its root element is not deserializing to a Workbook instance. Typically a corrupt or incomplete package, or one produced by a tool that did not write the workbook part.
Common situations: File truncated or partially written; package assembled incorrectly (missing workbook.xml); a template file that was emptied or corrupted; opening a non-xlsx file that happens to have a .xlsx extension.
Related errors
- Source sheet has no relationship id
- Source sheet not found: {newSheetName}
- Source sheet relationship does not resolve to a WorksheetPar
- Source range has no data
- Source range has no data rows
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/6f075280c0b24429.
Report an issue: GitHub.