{"record":{"id":"73533d8980574383","repo":"iOfficeAI/OfficeCLI","slug":"invalid-sort-mode-valid-asc-desc-locale","errorCode":null,"errorMessage":"invalid sort: '{mode}'. Valid: asc, desc, locale, locale-desc","messagePattern":"invalid sort: '(.+?)'\\. Valid: asc, desc, locale, locale-desc","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/PivotTableHelper.cs","lineNumber":379,"sourceCode":"    ///   using (PushAxisSortMode(properties)) { ... build pivot ... }\n    /// </summary>\n    private static readonly HashSet<string> _validSortModes = new(StringComparer.OrdinalIgnoreCase)\n    {\n        \"asc\", \"desc\", \"locale\", \"locale-desc\", \"none\"\n    };\n\n    private static IDisposable PushAxisSortMode(Dictionary<string, string> properties)\n    {\n        var prev = _axisSortMode;\n        if (properties.TryGetValue(\"sort\", out var mode) && !string.IsNullOrWhiteSpace(mode))\n        {\n            var normalized = mode.Trim().ToLowerInvariant();\n            // CONSISTENCY(strict-enums): unknown sort tokens are rejected\n            // up front. Empty / whitespace fall through to the default\n            // (no-op) so users can clear the sort by passing an empty\n            // value without seeing an error.\n            if (!_validSortModes.Contains(normalized))\n                throw new ArgumentException(\n                    $\"invalid sort: '{mode}'. Valid: asc, desc, locale, locale-desc\");\n            _axisSortMode = normalized;\n        }\n        return new SortModeScope(prev);\n    }\n\n    private sealed class SortModeScope : IDisposable\n    {\n        private readonly string? _prev;\n        public SortModeScope(string? prev) { _prev = prev; }\n        public void Dispose() { _axisSortMode = _prev; }\n    }\n\n    // ==================== Grand totals options ====================\n    //\n    // CONSISTENCY(thread-static-pivot-opts): reuses the same ThreadStatic\n    // pattern as _axisSortMode above. Grand totals need to reach the same\n    // ~15 nested sites (item builders, geometry, all 6 renderers, definition","sourceCodeStart":361,"sourceCodeEnd":397,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/PivotTableHelper.cs#L361-L397","documentation":"Thrown by PushAxisSortMode when the 'sort' property contains a token not in _validSortModes. The valid set is {asc, desc, locale, locale-desc, none} — note the error message lists only 'asc, desc, locale, locale-desc' and omits 'none', but 'none' IS accepted. Empty/whitespace values fall through as a no-op (to let users clear the sort without error), so only non-empty unknown tokens trigger this. Unknown sort modes are rejected up front (CONSISTENCY strict-enums) rather than silently ignored.","triggerScenarios":"Calling Add/Set pivot sort='ascending' (should be 'asc'); sort='descending'; sort='random'; or any token not in the valid set. Note: sort='none' is actually valid even though the error message does not list it.","commonSituations":"Using the full word 'ascending'/''ascending' instead of the abbreviation 'asc'; typo like sort='desec'; assuming a sort token that exists in Excel's UI but not in this library's vocabulary; version change where the accepted vocabulary differs from documentation.","solutions":["Use one of the accepted tokens: asc, desc, locale, locale-desc (or none to clear sorting).","Check for typos — 'asc' not 'ascending', 'desc' not 'descending'.","To clear/remove sorting, pass sort='' (empty) or sort='none'.","If the error persists with 'none', note that the message text omits it but it is valid."],"exampleFix":"// before\nSet pivot sort='ascending'\n// after\nSet pivot sort='asc'","handlingStrategy":"validation","validationCode":"var validSortModes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)\n    { \"asc\", \"desc\", \"locale\", \"locale-desc\", \"none\" };\nif (!string.IsNullOrWhiteSpace(sortMode) && !validSortModes.Contains(sortMode.Trim().ToLowerInvariant()))\n    throw new ArgumentException($\"Invalid sort mode '{sortMode}'. Valid: asc, desc, locale, locale-desc, none.\");","typeGuard":"static readonly HashSet<string> ValidSortModes =\n    new(StringComparer.OrdinalIgnoreCase) { \"asc\", \"desc\", \"locale\", \"locale-desc\", \"none\" };\nstatic bool IsValidSortMode(string mode) =>\n    string.IsNullOrWhiteSpace(mode) || ValidSortModes.Contains(mode.Trim().ToLowerInvariant());","tryCatchPattern":null,"preventionTips":["Use abbreviations: 'asc' not 'ascending', 'desc' not 'descending'.","Pass an empty string or 'none' to clear sorting without error.","Note that 'none' is valid even though the error message omits it.","Validate the sort token against the known set before calling Add/Set."],"tags":["pivot","excel","sort","enum","validation","input-validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}