iOfficeAI/OfficeCLI · error · System.ArgumentException

top10 conditional formatting requires rank >= 1 (got {rankIn

Error message

top10 conditional formatting requires rank >= 1 (got {rankInt}).

What it means

Thrown by the topn (top10) case in AddCfExtended when the parsed rank is a valid integer but <= 0. A top10 rule with rank 0 or negative is meaningless (rank 0 would select zero items) and would produce a cast to uint that misrepresents the intent. The guard runs after the int parse succeeds.

Source

Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Cf.cs:667

            typeLower = (properties.GetValueOrDefault("type", "") ?? "").ToLowerInvariant();

        switch (typeLower)
        {
            case "topn":
            {
                // Accept `rank=` (OOXML attribute name), `top=`/`bottomN=` (legacy
                // aliases), and `value=` (R26-1: matches the cellIs vocabulary so
                // users don't have to learn separate names per CF subtype).
                var rankStr = properties.GetValueOrDefault("rank")
                    ?? properties.GetValueOrDefault("top")
                    ?? properties.GetValueOrDefault("bottomN")
                    ?? properties.GetValueOrDefault("value")
                    ?? "10";
                if (!int.TryParse(rankStr, out var rankInt))
                    throw new ArgumentException(
                        $"top10 conditional formatting requires an integer rank (got '{rankStr}'). Use top=N or value=N.");
                if (rankInt <= 0)
                    throw new ArgumentException(
                        $"top10 conditional formatting requires rank >= 1 (got {rankInt}).");
                var rank = (uint)rankInt;
                var percent = ParseHelpers.IsTruthy(properties.GetValueOrDefault("percent", "false"));
                var bottom = ParseHelpers.IsTruthy(properties.GetValueOrDefault("bottom", "false"));
                cfNewRule = new ConditionalFormattingRule
                {
                    Type = ConditionalFormatValues.Top10,
                    Priority = cfNewPriority,
                    Rank = rank,
                    Percent = percent ? true : null,
                    Bottom = bottom ? true : null
                };
                break;
            }
            case "aboveaverage":
            {
                // `above=` is the legacy spelling; `aboveaverage=false`
                // (matching the cfType name) is accepted as an alias

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Set rank/top/value to an integer >= 1 (e.g. value=1 for the single top item).
  2. Omit the property to accept the default rank of 10.
  3. If the rank is computed, clamp it to a minimum of 1 before passing.

Example fix

// before: value=0
add /Sheet1/A1:A10 cf type=topn value=0
// after
add /Sheet1/A1:A10 cf type=topn value=1
Defensive patterns

Strategy: validation

Validate before calling

var rankStr = properties.GetValueOrDefault("rank") ?? properties.GetValueOrDefault("top")
    ?? properties.GetValueOrDefault("bottomN") ?? properties.GetValueOrDefault("value") ?? "10";
if (int.TryParse(rankStr, out var r) && r <= 0)
    throw new ArgumentException($"top10 rank must be >= 1 (got {r}).");

Type guard

static bool IsPositiveTop10Rank(string? s) => !int.TryParse(s, out var r) || r >= 1;

Try / catch

try { return Add(path, "topn", pos, props); }
catch (ArgumentException ex) when (ex.Message.Contains("rank >= 1"))
{ props["value"] = "1"; return Add(path, "topn", pos, props); }

Prevention

When it happens

Trigger: Calling Add with type=topn and a rank/top/bottomN/value property that parses as an integer <= 0. Examples: value=0, value=-5.

Common situations: Off-by-one expecting rank 0 to mean 'top item'; negative value from a computed input; default value of 0 from an unset variable in a calling script.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/69b4293c29b9067d. Report an issue: GitHub.