{"record":{"id":"1b9d67716f94e032","repo":"iOfficeAI/OfficeCLI","slug":"calculatedfield-requires-a-non-empty-name","errorCode":null,"errorMessage":"calculatedField requires a non-empty name","messagePattern":"calculatedField requires a non-empty name","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/PivotTableHelper.Definition.cs","lineNumber":1534,"sourceCode":"        var dataFields = pivotDef.DataFields;\n        if (dataFields == null)\n        {\n            dataFields = new DataFields { Count = 0u };\n            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","sourceCodeStart":1516,"sourceCodeEnd":1552,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/PivotTableHelper.Definition.cs#L1516-L1552","documentation":"Thrown by the calculated-field builder while iterating parsed specs: every spec must carry a non-empty 'name'. It fires after ParseCalculatedFieldSpecs has already accepted the entry, so an empty/whitespace name slipped through one of the input forms (JSON object, or colon-separated bare prop). The guard exists because Excel requires every cacheField to have a non-empty Name attribute and would reject the file on refresh.","triggerScenarios":"Passing calculatedField=\":=A1*2\" (bare-prop form with empty left side), or calculatedFields JSON like [{\"name\":\"\",\"formula\":\"=A1*2\"}] (note: JSON parser only filters null, not empty string, so \"\" reaches the loop), or a name consisting solely of whitespace like calculatedField=\"   :=A1*2\".","commonSituations":"User typos the colon separator (writes calculatedField==A1*2 thinking '=' starts the formula), malformed template substitution that leaves the name slot blank, or programmatic generation that builds the spec from an unset variable.","solutions":["Supply a non-empty, non-whitespace name before the colon: calculatedField=Margin:=Sales-Cost","If using JSON, ensure every object's 'name' is a non-empty string: [{\"name\":\"Margin\",\"formula\":\"=Sales-Cost\"}]","Trim and validate names in your own code before passing them to PivotTableHelper"],"exampleFix":"// before\ncalculatedField=\":=A1*2\"\n// after\ncalculatedField=\"Margin:=A1*2\"","handlingStrategy":"validation","validationCode":"// Before building the spec list, drop or reject entries with blank names\nvar specs = rawSpecs.Where(s => !string.IsNullOrWhiteSpace(s.Name)).ToList();\nif (rawSpecs.Count != specs.Count)\n    throw new InvalidOperationException(\"One or more calculated field names are empty\");","typeGuard":"static bool IsValidCalcFieldName(string? name) =>\n    !string.IsNullOrWhiteSpace(name) && name.Trim().Length > 0;","tryCatchPattern":"try { AddCalculatedFields(props); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"non-empty name\"))\n{ /* log and prompt user to supply a name */ }","preventionTips":["Always pair a name token with its formula before submitting a spec","Validate names with IsNullOrWhiteSpace in a pre-flight pass","Generate specs from strongly-typed records rather than ad-hoc strings"],"tags":["pivottable","calculated-field","argument-validation","input-parsing"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}