iOfficeAI/OfficeCLI · error · ArgumentException

Pivot name '{explicitName}' already exists in workbook

Error message

Pivot name '{explicitName}' already exists in workbook

What it means

Thrown when adding a PivotTable whose user-supplied 'name' property already matches an existing pivot name in the workbook. The collision check uses a case-insensitive HashSet of existing pivot names (PivotTableHelper.cs:1116) so 'Sales' and 'SALES' are treated as the same name. R6-1 enforces this because Excel would silently auto-rename on open but leave two pivots with identical names on disk.

Source

Thrown at src/officecli/Core/PivotTableHelper.cs:1263

        }

        // 5. Create PivotTablePart at worksheet level
        pivotPart = targetSheet.AddNewPart<PivotTablePart>();
        // Link pivot table to cache definition
        pivotPart.AddPart(cachePart);

        string pivotName;
        if (properties.TryGetValue("name", out var explicitName) && !string.IsNullOrEmpty(explicitName))
        {
            // R8-4 / R8-5 / R11-4 / R16-2: delegate all name validation to
            // ValidatePivotName so Add and Set share identical rules.
            explicitName = ValidatePivotName(explicitName);
            // R6-1: user-supplied name must be unique within the workbook.
            // Throw ArgumentException rather than silently allowing the
            // collision (Excel would auto-rename on open, but the on-disk
            // file would still carry two pivots with the same name).
            if (existingPivotNames.Contains(explicitName))
                throw new ArgumentException($"Pivot name '{explicitName}' already exists in workbook");
            pivotName = explicitName;
        }
        else
        {
            // R6-1: auto-generated default names must also avoid collisions
            // (two pivots on different sheets otherwise both pick
            // PivotTable{cacheId+1} with the same cacheId path).
            pivotName = $"PivotTable{cacheId + 1}";
            int bump = 1;
            while (existingPivotNames.Contains(pivotName))
            {
                bump++;
                pivotName = $"PivotTable{cacheId + bump}";
            }
        }
        var style = properties.GetValueOrDefault("style", "PivotStyleLight16");

        // columnNumFmtIds was resolved above (R19-1) and reused here to stamp

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Pass a unique name, or omit 'name' to let the host auto-generate a collision-free default.
  2. Before adding, query existing pivot names and either delete the old pivot or pick a distinct name.
  3. If scripting idempotent runs, guard with a check: delete the existing pivot of that name first if present.

Example fix

// before
properties["name"] = "SalesPivot"; // throws if it exists

// after
if (existingPivotNames.Contains("SalesPivot")) {
    // delete old pivot, then add
}
properties["name"] = "SalesPivot";
Defensive patterns

Strategy: validation

Validate before calling

// Before adding, gather existing pivot names (case-insensitive) and check.
var existing = new HashSet<string>(workbook.PivotTables.Select(p => p.Name), StringComparer.OrdinalIgnoreCase);
if (existing.Contains(desiredName))
    throw new InvalidOperationException($"Pick a unique name; '{desiredName}' is taken.");

Try / catch

try { AddPivot(props); }
catch (ArgumentException ex) when (ex.Message.Contains("already exists in workbook"))
{ /* retry with a suffixed unique name or surface to user */ }

Prevention

When it happens

Trigger: Calling add pivot with properties["name"] set to a string already present in the workbook's pivot set. Only fires for the explicit-name branch; auto-generated names (PivotTable{cacheId+1}) fall through to the bump loop at line 1273 and never throw.

Common situations: Re-running a script that adds a named pivot without first deleting the prior one; copy-pasting a pivot definition that hardcodes 'PivotTable1'; case-only differences ('Data' vs 'DATA') on case-insensitive filesystems/locales.

Related errors


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