{"record":{"id":"88d049ecca500bc0","repo":"iOfficeAI/OfficeCLI","slug":"calculatedfield-name-collides-with-an-existing","errorCode":null,"errorMessage":"calculatedField '{name}' collides with an existing field name","messagePattern":"calculatedField '(.+?)' collides with an existing field name","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/PivotTableHelper.Definition.cs","lineNumber":1538,"sourceCode":"            pivotDef.DataFields = dataFields;\n        }\n\n        // Mirror layout-dependent attributes (compact/outline) from an existing\n        // source pivotField so the calc fields stay attribute-consistent with\n        // the rest of the table. Excel rejects a pivotTable where some\n        // pivotFields declare compact=\"0\" outline=\"0\" but later ones omit them.\n        var templatePf = pivotFields.Elements<PivotField>().FirstOrDefault();\n        bool templateCompactFalse = templatePf?.Compact?.Value == false;\n        bool templateOutlineFalse = templatePf?.Outline?.Value == false;\n\n        foreach (var (name, formula) in specs)\n        {\n            if (string.IsNullOrWhiteSpace(name))\n                throw new ArgumentException(\"calculatedField requires a non-empty name\");\n            if (string.IsNullOrWhiteSpace(formula))\n                throw new ArgumentException($\"calculatedField '{name}' requires a non-empty formula\");\n            if (existingNames.Contains(name))\n                throw new ArgumentException(\n                    $\"calculatedField '{name}' collides with an existing field name\");\n            existingNames.Add(name);\n\n            // 1. cacheField\n            var cleanFormula = formula.TrimStart('=').Trim();\n            var cacheField = new CacheField\n            {\n                Name = name,\n                Formula = cleanFormula,\n                DatabaseField = false,\n                NumberFormatId = 0u\n            };\n            cacheFields.AppendChild(cacheField);\n\n            // New field index = position of the freshly-appended cacheField.\n            var newFieldIdx = (uint)(cacheFields.Elements<CacheField>().Count() - 1);\n            cacheFields.Count = (uint)cacheFields.Elements<CacheField>().Count();\n","sourceCodeStart":1520,"sourceCodeEnd":1556,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/PivotTableHelper.Definition.cs#L1520-L1556","documentation":"Each calculated field must have a unique name across both the existing source cacheFields and any prior calculated specs in the same call. The check is case-insensitive (existingNames uses StringComparer.OrdinalIgnoreCase) and runs against names collected from cacheFields plus names already added earlier in the loop. Excel itself would otherwise demote the duplicate, rename with a numeric suffix, or reject the file on refresh, so the helper fails fast with a precise message.","triggerScenarios":"Naming a calc field identically to an existing source column (calculatedField=Sales:=Sales*1.1 when 'Sales' is already a header); listing the same name twice in one call (calculatedFields=[{\"name\":\"X\",...},{\"name\":\"x\",...}]); re-adding a calc field that already exists in the pivot.","commonSituations":"User wants to 'override' a column by reusing its name; case variation between Excel-displayed and stored names; automation that regenerates a full spec list and forgets to clear the existing pivot first.","solutions":["Choose a distinct name for the calc field, e.g. calculatedField=SalesAdj:=Sales*1.1","If you intend to replace an existing calc field, delete the old one first so its name leaves existingNames","Check the Get readback for current field names before constructing the new spec"],"exampleFix":"// before\ncalculatedField=\"Sales:=Sales*1.1\"\n// after\ncalculatedField=\"SalesAdjusted:=Sales*1.1\"","handlingStrategy":"validation","validationCode":"// existingNames would come from the readback of current cache fields\nvar incoming = specs.Select(s => s.Name).Distinct(StringComparer.OrdinalIgnoreCase);\nvar dup = incoming.FirstOrDefault(n => existingNames.Contains(n));\nif (dup != null) throw new InvalidOperationException($\"Duplicate calc field name: {dup}\");","typeGuard":"static bool IsUniqueCalcName(string name, IEnumerable<string> existing) =>\n    !existing.Contains(name, StringComparer.OrdinalIgnoreCase);","tryCatchPattern":"try { AddCalculatedFields(props); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"collides\"))\n{ /* offer to delete the existing field or pick a new name */ }","preventionTips":["Read the Get readback to learn existing field names before submitting","Compute a case-insensitive duplicate check in your own layer","Adopt a naming convention (e.g. suffix 'Calc') to avoid collisions with source columns"],"tags":["pivottable","calculated-field","duplicate","argument-validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}