iOfficeAI/OfficeCLI · error · ArgumentException

Source sheet not found

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.

Solutions

  1. Verify the sheet name exists in the workbook with exact spelling and case (sheet names are case-sensitive in OOXML).
  2. If the sheet was renamed, pass the new name explicitly in the source spec: source=NewSheetName!A1:D10.
  3. 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.
  4. 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

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


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

Appendix: 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 the

View on GitHub (pinned to 1ced45e900)