iOfficeAI/OfficeCLI · error · ArgumentException
invalid sort: '{mode}'. Valid: asc, desc, locale, locale-des
Error message
invalid sort: '{mode}'. Valid: asc, desc, locale, locale-desc What it means
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.
Source
Thrown at src/officecli/Core/PivotTableHelper.cs:379
/// using (PushAxisSortMode(properties)) { ... build pivot ... }
/// </summary>
private static readonly HashSet<string> _validSortModes = new(StringComparer.OrdinalIgnoreCase)
{
"asc", "desc", "locale", "locale-desc", "none"
};
private static IDisposable PushAxisSortMode(Dictionary<string, string> properties)
{
var prev = _axisSortMode;
if (properties.TryGetValue("sort", out var mode) && !string.IsNullOrWhiteSpace(mode))
{
var normalized = mode.Trim().ToLowerInvariant();
// CONSISTENCY(strict-enums): unknown sort tokens are rejected
// up front. Empty / whitespace fall through to the default
// (no-op) so users can clear the sort by passing an empty
// value without seeing an error.
if (!_validSortModes.Contains(normalized))
throw new ArgumentException(
$"invalid sort: '{mode}'. Valid: asc, desc, locale, locale-desc");
_axisSortMode = normalized;
}
return new SortModeScope(prev);
}
private sealed class SortModeScope : IDisposable
{
private readonly string? _prev;
public SortModeScope(string? prev) { _prev = prev; }
public void Dispose() { _axisSortMode = _prev; }
}
// ==================== Grand totals options ====================
//
// CONSISTENCY(thread-static-pivot-opts): reuses the same ThreadStatic
// pattern as _axisSortMode above. Grand totals need to reach the same
// ~15 nested sites (item builders, geometry, all 6 renderers, definitionView on GitHub (pinned to 1ced45e900)
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.
Example fix
// before Set pivot sort='ascending' // after Set pivot sort='asc'
Defensive patterns
Strategy: validation
Validate before calling
var validSortModes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{ "asc", "desc", "locale", "locale-desc", "none" };
if (!string.IsNullOrWhiteSpace(sortMode) && !validSortModes.Contains(sortMode.Trim().ToLowerInvariant()))
throw new ArgumentException($"Invalid sort mode '{sortMode}'. Valid: asc, desc, locale, locale-desc, none."); Type guard
static readonly HashSet<string> ValidSortModes =
new(StringComparer.OrdinalIgnoreCase) { "asc", "desc", "locale", "locale-desc", "none" };
static bool IsValidSortMode(string mode) =>
string.IsNullOrWhiteSpace(mode) || ValidSortModes.Contains(mode.Trim().ToLowerInvariant()); Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Invalid subtotals '{s}'. Valid: on, off (default on)
- invalid layout: '{mode}'. Valid: compact, outline, tabular
- labelFilter type must be one of contains/doesNotContain/begi
- pivot name must not be empty
- labelFilter must be 'field:type:value', got: '{spec}'
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/73533d8980574383.
Report an issue: GitHub.