iOfficeAI/OfficeCLI · error · System.ArgumentException

Unsupported CF type: {typeLower}

Error message

Unsupported CF type: {typeLower}

What it means

Thrown by AddCfExtended's default switch arm when the resolved CF sub-type does not match any handled case. When the outer type is 'cfextended', the actual sub-type is read from properties['type'] and lowercased; if that value is not one of the implemented cases (topn, aboveaverage, uniquevalues, duplicatevalues, containstext, dateoccurring, belowaverage, containsblanks, notcontainsblanks, containserrors, notcontainserrors, contains, notcontains, beginswith, endswith), the default arm rejects it. This prevents silently emitting no rule or a wrong rule.

Source

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

                cfNewRule.AppendChild(new Formula($"LEFT({fc6},{btext.Length})=\"{btext}\""));
                break;
            }
            case "endswith":
            {
                var etext = properties.GetValueOrDefault("text", "");
                cfNewRule = new ConditionalFormattingRule
                {
                    Type = ConditionalFormatValues.EndsWith,
                    Priority = cfNewPriority,
                    Text = etext,
                    Operator = ConditionalFormattingOperatorValues.EndsWith
                };
                var fc7 = cfNewSqref.Split(':')[0].TrimStart('$');
                cfNewRule.AppendChild(new Formula($"RIGHT({fc7},{etext.Length})=\"{etext}\""));
                break;
            }
            default:
                throw new ArgumentException($"Unsupported CF type: {typeLower}");
        }

        ApplyStopIfTrue(cfNewRule, properties);

        // Build DXF formatting if fill/font properties are provided
        var cfNewDxf = new DifferentialFormat();
        bool cfNewHasDxf = false;
        if (properties.TryGetValue("font.color", out var cfNewFontColor))
        {
            var normalizedFontColor = ParseHelpers.NormalizeArgbColor(cfNewFontColor);
            cfNewDxf.Append(new Font(new DocumentFormat.OpenXml.Spreadsheet.Color { Rgb = normalizedFontColor }));
            cfNewHasDxf = true;
        }
        else if (properties.TryGetValue("font.bold", out var cfNewFontBold) && IsTruthy(cfNewFontBold))
        {
            cfNewDxf.Append(new Font(new Bold()));
            cfNewHasDxf = true;
        }

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Use a CF type handled by the correct method: databar, colorscale, iconset, formula, cellis go to their own Add paths — do not route them through cfextended.
  2. For extended types, use one of: topn, aboveaverage, belowaverage, uniquevalues, duplicatevalues, containstext, contains, notcontains, beginswith, endswith, containsblanks, notcontainsblanks, containserrors, notcontainserrors, dateoccurring.
  3. Check the spelling and casing of the type property.

Example fix

// before: routing colorscale through cfextended
add /Sheet1/A1:A10 cfextended type=colourScale
// after: use the dedicated colorscale path
add /Sheet1/A1:A10 colorscale mincolor=F8696B maxcolor=63BE7B
Defensive patterns

Strategy: validation

Validate before calling

var extended = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{ "topn","aboveaverage","belowaverage","uniquevalues","duplicatevalues","containstext","contains","notcontains",
  "beginswith","endswith","containsblanks","notcontainsblanks","containserrors","notcontainserrors","dateoccurring" };
var ownMethods = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{ "databar","colorscale","iconset","formula","cellis" };
var t = properties.GetValueOrDefault("type", "");
if (ownMethods.Contains(t)) throw new ArgumentException($"Type '{t}' has its own Add path; do not route via cfextended.");
if (!extended.Contains(t)) throw new ArgumentException($"CF type '{t}' not handled by cfextended.");

Type guard

static readonly HashSet<string> CfExtendedTypes = new(StringComparer.OrdinalIgnoreCase)
{ "topn","aboveaverage","belowaverage","uniquevalues","duplicatevalues","containstext","contains","notcontains",
  "beginswith","endswith","containsblanks","notcontainsblanks","containserrors","notcontainserrors","dateoccurring" };
static bool IsCfExtendedType(string? s) => s is not null && CfExtendedTypes.Contains(s);

Try / catch

try { return Add(path, "cfextended", pos, props); }
catch (ArgumentException ex) when (ex.Message.StartsWith("Unsupported CF type"))
{ /* route databar/colorscale/iconset/formula/cellis to their own Add paths */ throw; }

Prevention

When it happens

Trigger: Calling Add routed to AddCfExtended (either via type=cfextended with properties.type=<x>, or via the AddCf/AddDataBar dispatch mapping an unknown extended sub-type) where <x> is not in the implemented case list. Example: type=cfextended with properties type=databar (databar is handled by a different method), type=colorscale, or a typo like type=colourScale.

Common situations: Dispatch routing sends a type to cfextended that actually belongs to a different handler (databar/colorscale/iconset/formula/cellIs have their own methods); typo in the sub-type; a new/undocumented CF type the handler does not yet support.

Related errors


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