{"record":{"id":"5f7d0453a4bee243","repo":"iOfficeAI/OfficeCLI","slug":"unsupported-cf-type-typelower","errorCode":null,"errorMessage":"Unsupported CF type: {typeLower}","messagePattern":"Unsupported CF type: (.+?)","errorType":"validation","errorClass":"System.ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Cf.cs","lineNumber":902,"sourceCode":"                cfNewRule.AppendChild(new Formula($\"LEFT({fc6},{btext.Length})=\\\"{btext}\\\"\"));\n                break;\n            }\n            case \"endswith\":\n            {\n                var etext = properties.GetValueOrDefault(\"text\", \"\");\n                cfNewRule = new ConditionalFormattingRule\n                {\n                    Type = ConditionalFormatValues.EndsWith,\n                    Priority = cfNewPriority,\n                    Text = etext,\n                    Operator = ConditionalFormattingOperatorValues.EndsWith\n                };\n                var fc7 = cfNewSqref.Split(':')[0].TrimStart('$');\n                cfNewRule.AppendChild(new Formula($\"RIGHT({fc7},{etext.Length})=\\\"{etext}\\\"\"));\n                break;\n            }\n            default:\n                throw new ArgumentException($\"Unsupported CF type: {typeLower}\");\n        }\n\n        ApplyStopIfTrue(cfNewRule, properties);\n\n        // Build DXF formatting if fill/font properties are provided\n        var cfNewDxf = new DifferentialFormat();\n        bool cfNewHasDxf = false;\n        if (properties.TryGetValue(\"font.color\", out var cfNewFontColor))\n        {\n            var normalizedFontColor = ParseHelpers.NormalizeArgbColor(cfNewFontColor);\n            cfNewDxf.Append(new Font(new DocumentFormat.OpenXml.Spreadsheet.Color { Rgb = normalizedFontColor }));\n            cfNewHasDxf = true;\n        }\n        else if (properties.TryGetValue(\"font.bold\", out var cfNewFontBold) && IsTruthy(cfNewFontBold))\n        {\n            cfNewDxf.Append(new Font(new Bold()));\n            cfNewHasDxf = true;\n        }","sourceCodeStart":884,"sourceCodeEnd":920,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Cf.cs#L884-L920","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","For extended types, use one of: topn, aboveaverage, belowaverage, uniquevalues, duplicatevalues, containstext, contains, notcontains, beginswith, endswith, containsblanks, notcontainsblanks, containserrors, notcontainserrors, dateoccurring.","Check the spelling and casing of the type property."],"exampleFix":"// before: routing colorscale through cfextended\nadd /Sheet1/A1:A10 cfextended type=colourScale\n// after: use the dedicated colorscale path\nadd /Sheet1/A1:A10 colorscale mincolor=F8696B maxcolor=63BE7B","handlingStrategy":"validation","validationCode":"var extended = new HashSet<string>(StringComparer.OrdinalIgnoreCase)\n{ \"topn\",\"aboveaverage\",\"belowaverage\",\"uniquevalues\",\"duplicatevalues\",\"containstext\",\"contains\",\"notcontains\",\n  \"beginswith\",\"endswith\",\"containsblanks\",\"notcontainsblanks\",\"containserrors\",\"notcontainserrors\",\"dateoccurring\" };\nvar ownMethods = new HashSet<string>(StringComparer.OrdinalIgnoreCase)\n{ \"databar\",\"colorscale\",\"iconset\",\"formula\",\"cellis\" };\nvar t = properties.GetValueOrDefault(\"type\", \"\");\nif (ownMethods.Contains(t)) throw new ArgumentException($\"Type '{t}' has its own Add path; do not route via cfextended.\");\nif (!extended.Contains(t)) throw new ArgumentException($\"CF type '{t}' not handled by cfextended.\");","typeGuard":"static readonly HashSet<string> CfExtendedTypes = new(StringComparer.OrdinalIgnoreCase)\n{ \"topn\",\"aboveaverage\",\"belowaverage\",\"uniquevalues\",\"duplicatevalues\",\"containstext\",\"contains\",\"notcontains\",\n  \"beginswith\",\"endswith\",\"containsblanks\",\"notcontainsblanks\",\"containserrors\",\"notcontainserrors\",\"dateoccurring\" };\nstatic bool IsCfExtendedType(string? s) => s is not null && CfExtendedTypes.Contains(s);","tryCatchPattern":"try { return Add(path, \"cfextended\", pos, props); }\ncatch (ArgumentException ex) when (ex.Message.StartsWith(\"Unsupported CF type\"))\n{ /* route databar/colorscale/iconset/formula/cellis to their own Add paths */ throw; }","preventionTips":["Route databar/colorscale/iconset/formula/cellis to their dedicated Add methods.","For extended types, use the exact case-insensitive token from the case list.","Confirm the type spelling before dispatch."],"tags":["excel","conditional-formatting","cfextended","dispatch","enum-validation","argument-validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}