iOfficeAI/OfficeCLI · error · ArgumentException
Source sheet not found: {newSheetName}
Error message
Source sheet not found: {newSheetName} What it means
Thrown by RefreshPivotCacheFromSource when re-binding an existing pivot to a new source range via Set source=. The sheet name (parsed from the spec before '!' e.g. 'Sheet1!A1:D10', or the cache's previously-stored sheet name if the spec has no '!') does not match any <Sheet> element in Workbook.Sheets. OOXML registers worksheet tabs there, so the pivot's WorksheetSource.Sheet must resolve to one of those entries by exact name match.
Source
Thrown at src/officecli/Core/PivotTableHelper.Readback.cs:407
if (newSourceSpec.Contains('!'))
{
var parts = newSourceSpec.Split('!', 2);
newSheetName = parts[0].Trim().Trim('\'', '"').Trim();
newRef = parts[1].Trim();
}
else
{
newSheetName = existingWsSource.Sheet?.Value ?? "";
newRef = newSourceSpec;
}
// Locate the source worksheet via the workbook part.
var workbookPart = pivotPart.GetParentParts().OfType<WorksheetPart>().FirstOrDefault()
?.GetParentParts().OfType<WorkbookPart>().FirstOrDefault()
?? throw new InvalidOperationException("Workbook part not reachable from pivot table part");
var sheetEntry = workbookPart.Workbook?.Sheets?.Elements<Sheet>()
.FirstOrDefault(s => s.Name?.Value == newSheetName)
?? throw new ArgumentException($"Source sheet not found: {newSheetName}");
if (sheetEntry.Id?.Value is not string srcRelId)
throw new InvalidOperationException("Source sheet has no relationship id");
var sourceWsPart = workbookPart.GetPartById(srcRelId) as WorksheetPart
?? throw new InvalidOperationException("Source sheet relationship does not resolve to a WorksheetPart");
// Re-read source data from the new range.
var (headers, columnData, _) = ReadSourceData(sourceWsPart, newRef);
if (headers.Length == 0)
throw new ArgumentException("Source range has no data");
if (columnData.Count == 0 || columnData[0].Length == 0)
throw new ArgumentException("Source range has no data rows");
// R15-2: Before mutating any cache/pivot state, validate that existing
// row/col/value/filter field references still fit inside the new
// (possibly narrower) header list. A silent drop or index clamp here
// would leave the DataFields pointing past the rendered columnData,
// crashing RenderPivotIntoSheet with ArgumentOutOfRangeException.
// Prefer strict error over data loss: user must explicitly restate theView on GitHub (pinned to 1ced45e900)
Solutions
- Verify the sheet name exists in the workbook with exact spelling and case (sheet names are case-sensitive in OOXML).
- If the sheet was renamed, pass the new name explicitly in the source spec: source=NewSheetName!A1:D10.
- If you want to keep the same sheet as the existing cache, use the bare-range form source=A1:D10 without a sheet qualifier so it reuses existingWsSource.Sheet.
- List workbook sheets first (Get workbook sheets) to confirm the exact tab name before calling Set source=.
Example fix
// before — sheet was renamed from 'Data' to 'Sales' Set pivot source=Data!A1:F100 // after Set pivot source=Sales!A1:F100
Defensive patterns
Strategy: validation
Validate before calling
// Before calling Set source=, verify the sheet exists
var sheets = workbookPart.Workbook?.Sheets?.Elements<Sheet>()
.Select(s => s.Name?.Value)
.Where(n => n != null)
.ToHashSet(StringComparer.Ordinal);
var specSheet = sourceSpec.Contains('!')
? sourceSpec.Split('!', 2)[0].Trim().Trim('\'', '"').Trim()
: existingCacheSheetName;
if (sheets == null || !sheets.Contains(specSheet))
throw new InvalidOperationException($"Sheet '{specSheet}' not found. Available: {string.Join(", ", sheets ?? new HashSet<string>())}"); Prevention
- List workbook sheets before referencing one in a source spec.
- Treat sheet names as case-sensitive — OOXML matches by Ordinal comparison.
- If a sheet was renamed, update all source specs that reference it.
- Use the bare-range form (A1:D10 without Sheet!) when you want to reuse the cache's existing sheet.
When it happens
Trigger: Calling SetPivotTableProperties with source=Foo!A1:D10 where 'Foo' is not a tab in the workbook. Or calling source=A1:D10 (no sheet qualifier) when the existing cache's stored WorksheetSource.Sheet value is stale because the worksheet was renamed or deleted after the pivot was created.
Common situations: Renaming a worksheet after the pivot was created, leaving a stale sheet name in the cache source; typo in the CLI source= argument (wrong case, trailing space, quote mismatch); copy-pasting a source spec from a different workbook; sheet name contains leading/trailing whitespace that the Trim('\\\'','\"') in the parser does not fully normalize.
Related errors
- Source sheet has no relationship id
- Source sheet relationship does not resolve to a WorksheetPar
- Source range has no data
- Source range has no data rows
- {axis} field '{fieldRef}' (index {idx}) is out of range afte
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/97f8e9b872039ae3.
Report an issue: GitHub.