{"record":{"id":"32721b50412c0cb5","repo":"iOfficeAI/OfficeCLI","slug":"invalid-json-for-calculatedfields-ex-message","errorCode":null,"errorMessage":"invalid JSON for calculatedFields: {ex.Message}","messagePattern":"invalid JSON for calculatedFields: (.+?)","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/PivotTableHelper.Definition.cs","lineNumber":1732,"sourceCode":"                if (doc.RootElement.ValueKind != System.Text.Json.JsonValueKind.Array)\n                    throw new ArgumentException(\"'calculatedFields' must be a JSON array\");\n                foreach (var el in doc.RootElement.EnumerateArray())\n                {\n                    if (el.ValueKind != System.Text.Json.JsonValueKind.Object)\n                        throw new ArgumentException(\"each calculatedFields entry must be a JSON object\");\n                    string? name = null, formula = null;\n                    foreach (var p in el.EnumerateObject())\n                    {\n                        if (p.NameEquals(\"name\")) name = p.Value.GetString();\n                        else if (p.NameEquals(\"formula\")) formula = p.Value.GetString();\n                    }\n                    if (name != null && formula != null)\n                        result.Add((name, formula));\n                }\n            }\n            catch (System.Text.Json.JsonException ex)\n            {\n                throw new ArgumentException($\"invalid JSON for calculatedFields: {ex.Message}\");\n            }\n        }\n\n        // Numbered + bare calculatedField props (ordinal sort so calculatedField1\n        // appears before calculatedField2 regardless of insertion order).\n        var cfKeys = properties.Keys\n            .Where(k => System.Text.RegularExpressions.Regex.IsMatch(\n                k, @\"^calculatedField\\d*$\", System.Text.RegularExpressions.RegexOptions.IgnoreCase))\n            .OrderBy(k => k, StringComparer.OrdinalIgnoreCase)\n            .ToList();\n        foreach (var key in cfKeys)\n        {\n            var raw = properties[key];\n            if (string.IsNullOrWhiteSpace(raw)) continue;\n            var colonIdx = raw.IndexOf(':');\n            if (colonIdx < 0)\n                throw new ArgumentException(\n                    $\"calculatedField '{raw}' must be 'Name:=Formula' (colon-separated)\");","sourceCodeStart":1714,"sourceCodeEnd":1750,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/PivotTableHelper.Definition.cs#L1714-L1750","documentation":"The 'calculatedFields' string could not be parsed as JSON at all — System.Text.Json threw a JsonException, which the helper wraps in an ArgumentException with the parser's own message appended. This is a hard parse failure (trailing comma, unquoted key, single quotes, unterminated string), not a shape problem. The inner exception text identifies the byte position of the syntax error.","triggerScenarios":"Trailing comma: calculatedFields=[{\"name\":\"X\",\"formula\":\"=A1\"},]; single-quoted keys (JSON requires double quotes); unescaped quotes inside the value; unterminated array or object; stray characters around the JSON.","commonSituations":"Hand-written JSON in a CLI argument that breaks under shell quoting; values containing quotes that weren't escaped; copy-paste from a pretty-printed source that picked up a comment or trailing punctuation; CRLF/encoding artefacts.","solutions":["Run the JSON through a linter/validator before passing it; the inner exception pinpoints the position","For anything beyond one field, prefer the singular calculatedField/ calculatedField1 / calculatedField2 props to avoid shell-JSON friction","Ensure double quotes around keys and string values, no trailing commas, and proper escaping of inner quotes"],"exampleFix":"// before\ncalculatedFields=\"[{name:'X',formula:'=A1'}]\"\n// after\ncalculatedFields=\"[{\\\"name\\\":\\\"X\\\",\\\"formula\\\":\\\"=A1\\\"}]\"","handlingStrategy":"try-catch","validationCode":"try { using var _ = System.Text.Json.JsonDocument.Parse(jsonRaw); }\ncatch (System.Text.Json.JsonException ex)\n{ throw new InvalidOperationException($\"calculatedFields JSON is invalid: {ex.Message}\"); }","typeGuard":"static bool IsValidJson(string json)\n{\n    try { using var _ = JsonDocument.Parse(json); return true; }\n    catch { return false; }\n}","tryCatchPattern":"try { AddCalculatedFields(props); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"invalid JSON for calculatedFields\"))\n{ /* show inner parser message and re-prompt */ }","preventionTips":["Run JSON through a linter before submitting","Generate JSON with a serializer rather than string concatenation","Watch for trailing commas, single quotes, and unescaped inner quotes under shell quoting"],"tags":["pivottable","calculated-field","json","parse-error","argument-validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}