{"record":{"id":"7719726b72ddb60f","repo":"iOfficeAI/OfficeCLI","slug":"invalid-showdataas-showas-valid-normal-per","errorCode":null,"errorMessage":"invalid showDataAs: '{showAs}'. Valid: normal, percent_of_total, percent_of_row, percent_of_col, running_total","messagePattern":"invalid showDataAs: '(.+?)'\\. Valid: normal, percent_of_total, percent_of_row, percent_of_col, running_total","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/PivotTableHelper.Parse.cs","lineNumber":464,"sourceCode":"            \"\" or \"normal\" => null,\n            \"percent_of_total\" or \"percentoftotal\" or \"percent\" => ShowDataAsValues.PercentOfTotal,\n            \"percent_of_row\" or \"percentofrow\" => ShowDataAsValues.PercentOfRaw,\n            \"percent_of_col\" or \"percent_of_column\" or \"percentofcol\" or \"percentofcolumn\" => ShowDataAsValues.PercentOfColumn,\n            \"running_total\" or \"runningtotal\" or \"runtotal\" => ShowDataAsValues.RunTotal,\n            // CONSISTENCY(strict-enums): difference / percent_diff / index are\n            // accepted by the OOXML ShowDataAsValues enum, but ApplyShowDataAs1x1\n            // has no matrix transformation for them, so rendered cells would\n            // silently equal the raw aggregate. Reject up front until a proper\n            // renderer exists, mirroring the invalid-sort / invalid-aggregate\n            // policy from Round 1.\n            \"difference\" or \"diff\" or \"percent_diff\" or \"percentdiff\" or \"index\" =>\n                throw new ArgumentException(\n                    $\"showDataAs '{showAs}' is not yet supported by the renderer \" +\n                    \"(would silently return raw aggregate). Supported: normal, \" +\n                    \"percent_of_total, percent_of_row, percent_of_col, running_total.\"),\n            // CONSISTENCY(strict-enums): unknown showAs tokens are rejected\n            // up front so users see typos at Add/Set time, not on render.\n            _ => throw new ArgumentException(\n                $\"invalid showDataAs: '{showAs}'. Valid: normal, percent_of_total, percent_of_row, \" +\n                \"percent_of_col, running_total\"),\n        };\n    }\n\n    // R11-2: Right-to-left value-spec parser support. Token recognizers\n    // mirror the cases ParseSubtotal / ParseShowDataAs accept (lowercase\n    // canonical only — we lowercase the token before calling). Keep these\n    // in sync if new aggregates / showAs tokens are added downstream.\n    private static bool IsKnownAggregateToken(string token) => token switch\n    {\n        \"sum\" or \"count\" or \"countnums\" or \"countnum\" or \"average\" or \"avg\" or\n        \"max\" or \"min\" or \"product\" or \"stddev\" or \"std\" or \"stddevp\" or \"stdp\" or\n        \"var\" or \"variance\" or \"varp\" => true,\n        _ => false,\n    };\n\n    private static bool IsKnownShowAsToken(string token) => token switch","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/PivotTableHelper.Parse.cs#L446-L482","documentation":"The showAs token did not match any recognised spelling (snake_case or camelCase aliases) and was not one of the explicitly-unsupported-but-known tokens either. The default switch arm rejects it so users see typos at Add/Set time rather than getting a silent fallback to 'normal'. The message enumerates the valid tokens.","triggerScenarios":"values=Sales:sum:pecent_of_total (typo 'pecent'); values=Sales:sum:Percentage (not a recognised alias); values=Sales:sum:run_total (wrong separator — should be running_total).","commonSituations":"Typos; users guessing at token names from Excel UI labels rather than the CLI vocabulary; case or separator mistakes (the parser lowercases first, but the literal spelling must still match).","solutions":["Use one of the exact valid tokens: normal, percent_of_total, percent_of_row, percent_of_col, running_total","Drop the showAs segment entirely if you want the default 'normal'","Double-check spelling and separators against the message's valid list"],"exampleFix":"// before\nvalues=\"Sales:sum:pecent_of_total\"\n// after\nvalues=\"Sales:sum:percent_of_total\"","handlingStrategy":"validation","validationCode":"var valid = new[] { \"normal\", \"percent_of_total\", \"percent_of_row\", \"percent_of_col\", \"running_total\" };\nif (!valid.Contains(showAs.ToLowerInvariant()))\n    throw new InvalidOperationException($\"Invalid showDataAs '{showAs}'\");","typeGuard":"static readonly HashSet<string> ValidShowAs = new(StringComparer.OrdinalIgnoreCase)\n{ \"\", \"normal\", \"percent_of_total\", \"percentoftotal\", \"percent\",\n  \"percent_of_row\", \"percentofrow\",\n  \"percent_of_col\", \"percent_of_column\", \"percentofcol\", \"percentofcolumn\",\n  \"running_total\", \"runningtotal\", \"runtotal\" };\nstatic bool IsValidShowAs(string s) => ValidShowAs.Contains(s);","tryCatchPattern":"try { BuildPivot(props); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"invalid showDataAs\"))\n{ /* correct the spelling against the valid list in the message */ }","preventionTips":["Copy token spellings from the valid list in the message","Drop the showAs segment to default to 'normal'","Beware separator and case mistakes"],"tags":["pivottable","showdataas","strict-enum","typo","argument-validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}