iOfficeAI/OfficeCLI · error · System.ArgumentException

Unknown CF type '{cfTypeRaw}'. Valid: databar, iconset, colo

Error message

Unknown CF type '{cfTypeRaw}'. Valid: databar, iconset, colorscale, formula, cellIs, top10, topPercent, bottom, bottomPercent, aboveAverage, belowAverage, uniqueValues, duplicateValues, containsText, notContains, beginsWith, endsWith, containsBlanks, notContainsBlanks, containsErrors, notContainsErrors, dateOccurring.

What it means

Thrown by AddCf (the cf alias dispatcher) when the type or rule property does not match any known conditional-formatting type. The switch has no silent default: an unrecognized value throws instead of falling back to dataBar, so typos surface immediately. The error message lists the full allowlist of valid type names.

Source

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

            // user-facing aliases for the OOXML `top10` cfRule. Without this
            // mapping, the dispatch fell through to the default `databar`
            // branch and silently rewrote the rule type. Set `percent`/
            // `bottom` properties so the topn branch emits the right attrs.
            "topn" or "top10" or "top" => Add(parentPath, "topn", position, properties),
            "toppercent" => AddTopRouted(parentPath, position, properties, percent: true, bottom: false),
            "bottom" => AddTopRouted(parentPath, position, properties, percent: false, bottom: true),
            "bottompercent" => AddTopRouted(parentPath, position, properties, percent: true, bottom: true),
            "aboveaverage" => Add(parentPath, "aboveaverage", position, properties),
            "uniquevalues" => Add(parentPath, "uniquevalues", position, properties),
            "duplicatevalues" => Add(parentPath, "duplicatevalues", position, properties),
            "containstext" => Add(parentPath, "containstext", position, properties),
            "dateoccurring" or "timeperiod" => Add(parentPath, "dateoccurring", position, properties),
            "belowaverage" or "containsblanks" or "notcontainsblanks" or "containserrors" or "notcontainserrors" or "contains" or "notcontains" or "beginswith" or "endswith"
                => Add(parentPath, "cfextended", position, properties),
            // Reject unknown CF types instead of silently falling back to
            // dataBar — silent fallback hides typos like `type=badtype` and
            // produces a rule the user did not ask for.
            _ => throw new ArgumentException(
                $"Unknown CF type '{cfTypeRaw}'. Valid: databar, iconset, colorscale, formula, cellIs, "
                + "top10, topPercent, bottom, bottomPercent, aboveAverage, belowAverage, "
                + "uniqueValues, duplicateValues, containsText, notContains, beginsWith, endsWith, "
                + "containsBlanks, notContainsBlanks, containsErrors, notContainsErrors, dateOccurring.")
        };
    }

    // R39-1: thread `percent`/`bottom` flags into the topn branch so that
    // `type=topPercent` / `type=bottom` / `type=bottomPercent` route to the
    // same `top10` cfRule with the right attributes set, instead of falling
    // through to the dataBar default. Mutates `properties` in place; keys
    // already supplied by the user take precedence.
    private string AddTopRouted(string parentPath, InsertPosition? position, Dictionary<string, string> properties, bool percent, bool bottom)
    {
        if (!properties.ContainsKey("percent")) properties["percent"] = percent ? "true" : "false";
        if (!properties.ContainsKey("bottom")) properties["bottom"] = bottom ? "true" : "false";
        return Add(parentPath, "topn", position, properties);
    }

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Correct the type/rule value to one from the allowlist in the error message.
  2. If omitted, type defaults to databar for the cf alias; remove the type property to get a data bar.
  3. For highlight, also supply operator= so it routes to cellIs.

Example fix

// before
props["type"] = "databars"; // typo
handler.Add("/Sheet1", "cf", null, props);

// after
props["type"] = "databar";
handler.Add("/Sheet1", "cf", null, props);
Defensive patterns

Strategy: validation

Validate before calling

static readonly HashSet<string> CfTypes = new(StringComparer.OrdinalIgnoreCase)
{ "databar","iconset","colorscale","formula","expression","cellis","highlight","topn","top10","top","toppercent","bottom","bottompercent","aboveaverage","belowaverage","uniquevalues","duplicatevalues","containstext","dateoccurring","timeperiod","containsblanks","notcontainsblanks","containserrors","notcontainserrors","contains","notcontains","beginswith","endswith" };
var t = props.GetValueOrDefault("type") ?? props.GetValueOrDefault("rule");
if (t != null && !CfTypes.Contains(t))
    throw new ArgumentOutOfRangeException("type", $"Unknown CF type: {t}");
handler.Add("/Sheet1", "cf", null, props);

Type guard

static bool IsKnownCfType(string? t) => t == null || CfTypes.Contains(t);

Prevention

When it happens

Trigger: Add type=cf with properties["type"]="badtype", or rule="databars" (plural typo), or any value not in the allowlist (databar, iconset, colorscale, formula, expression, cellIs, highlight, topn, top10, top, topPercent, bottom, bottomPercent, aboveAverage, belowAverage, uniqueValues, duplicateValues, containsText, dateOccurring, timePeriod, containsBlanks, notContainsBlanks, containsErrors, notContainsErrors, contains, notContains, beginsWith, endsWith). The comparison is case-insensitive.

Common situations: Typo in the type name (e.g. databars, colorScale vs colorscale). Using an Excel UI label that is not in the allowlist. Copying a type from documentation for a different library version. Note highlight requires an operator property to route to cellIs; without it, highlight is not matched and falls to the default throw.

Related errors


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