{"record":{"id":"e71ee17fe1083ea7","repo":"iOfficeAI/OfficeCLI","slug":"unknown-cf-type-cftypeprop-valid-databar-ic","errorCode":null,"errorMessage":"Unknown CF type '{cfTypeProp}'. Valid: databar, iconset, colorscale, formula, cellIs, top10, topPercent, bottom, bottomPercent, aboveAverage, belowAverage, uniqueValues, duplicateValues, containsText, notContains, beginsWith, endsWith, containsBlanks, notContainsBlanks, containsErrors, notContainsErrors, dateOccurring.","messagePattern":"Unknown CF type '(.+?)'\\. Valid: databar, iconset, colorscale, formula, cellIs, top10, topPercent, bottom, bottomPercent, aboveAverage, belowAverage, uniqueValues, duplicateValues, containsText, notContains, beginsWith, endsWith, containsBlanks, notContainsBlanks, containsErrors, notContainsErrors, dateOccurring\\.","errorType":"validation","errorClass":"System.ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Cf.cs","lineNumber":116,"sourceCode":"            if (cfTypeLower is \"topn\" or \"top10\" or \"top\") return Add(parentPath, \"topn\", position, properties);\n            if (cfTypeLower is \"toppercent\") return AddTopRouted(parentPath, position, properties, percent: true, bottom: false);\n            if (cfTypeLower is \"bottom\") return AddTopRouted(parentPath, position, properties, percent: false, bottom: true);\n            if (cfTypeLower is \"bottompercent\") return AddTopRouted(parentPath, position, properties, percent: true, bottom: true);\n            if (cfTypeLower is \"aboveaverage\") return Add(parentPath, \"aboveaverage\", position, properties);\n            if (cfTypeLower is \"uniquevalues\") return Add(parentPath, \"uniquevalues\", position, properties);\n            if (cfTypeLower is \"duplicatevalues\") return Add(parentPath, \"duplicatevalues\", position, properties);\n            if (cfTypeLower is \"containstext\") return Add(parentPath, \"containstext\", position, properties);\n            if (cfTypeLower is \"dateoccurring\" or \"timeperiod\") return Add(parentPath, \"dateoccurring\", position, properties);\n            if (cfTypeLower is \"belowaverage\" or \"containsblanks\" or \"notcontainsblanks\" or \"containserrors\" or \"notcontainserrors\" or \"contains\" or \"notcontains\" or \"beginswith\" or \"endswith\")\n                return Add(parentPath, \"cfextended\", position, properties);\n            // R10: Reject unknown CF types instead of silently falling through to\n            // dataBar. The `cf` alias (AddCf) already throws on unknowns; mirror\n            // the behavior here so both `--type cf` and `--type conditionalformatting`\n            // share the same allowlist (CONSISTENCY(cf-type-allowlist)). `databar`\n            // is the documented default for this alias, so allow it explicitly.\n            if (cfTypeLower is not \"databar\")\n            {\n                throw new ArgumentException(\n                    $\"Unknown CF type '{cfTypeProp}'. Valid: databar, iconset, colorscale, formula, cellIs, \"\n                    + \"top10, topPercent, bottom, bottomPercent, aboveAverage, belowAverage, \"\n                    + \"uniqueValues, duplicateValues, containsText, notContains, beginsWith, endsWith, \"\n                    + \"containsBlanks, notContainsBlanks, containsErrors, notContainsErrors, dateOccurring.\");\n            }\n        }\n        var cfSegments = parentPath.TrimStart('/').Split('/', 2);\n        var cfSheetName = cfSegments[0];\n        var cfWorksheet = FindWorksheet(cfSheetName)\n            ?? throw new ArgumentException($\"Sheet not found: {cfSheetName}\");\n\n        // R22-2: a path-tail range (/Sheet1/A1:A3) is the sqref fallback before\n        // the hardcoded \"A1:A10\" — previously csSegments[1] was silently ignored.\n        var cfPathRange = cfSegments.Length > 1 && !string.IsNullOrEmpty(cfSegments[1]) ? cfSegments[1] : \"A1:A10\";\n        var sqref = ValidateSqref(properties.GetValueOrDefault(\"sqref\") ?? properties.GetValueOrDefault(\"range\") ?? properties.GetValueOrDefault(\"ref\", cfPathRange), \"ref\");\n        var minVal = properties.ContainsKey(\"min\") ? properties[\"min\"] : (string?)null;\n        var maxVal = properties.ContainsKey(\"max\") ? properties[\"max\"] : (string?)null;\n        // The schema documents min/max as \"numeric or 'auto'\". 'auto' is the","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Cf.cs#L98-L134","documentation":"Thrown by AddDataBar (the conditionalformatting alias) when a type or rule property is supplied but does not match any known CF type and is not databar. This mirrors the AddCf allowlist (CONSISTENCY cf-type-allowlist) so both --type cf and --type conditionalformatting reject the same unknowns. databar is the documented default for this alias, so it is allowed explicitly; everything else unrecognized throws.","triggerScenarios":"Add type=conditionalformatting with properties[\"type\"]=\"badtype\" or rule=\"colorscaleX\". Any value not in the shared allowlist and not databar. The guard only runs when a type/rule property is present; omitting it yields a plain data bar. Case-insensitive comparison via ToLowerInvariant.","commonSituations":"Typo in the type name. Using a type valid for the cf alias but spelled differently. Passing a type meant for a different element. Copying a value from older docs whose allowlist differed.","solutions":["Correct the type/rule to a value from the allowlist in the message.","Omit the type property to get the default data bar for this alias.","Use the cf alias (type=cf) if you prefer its default-dispatch behavior."],"exampleFix":"// before\nprops[\"type\"] = \"coloscale\"; // typo\nhandler.Add(\"/Sheet1\", \"conditionalformatting\", null, props);\n\n// after\nprops[\"type\"] = \"colorscale\";\nhandler.Add(\"/Sheet1\", \"conditionalformatting\", null, props);","handlingStrategy":"validation","validationCode":"static readonly HashSet<string> CfTypes = new(StringComparer.OrdinalIgnoreCase)\n{ \"databar\",\"iconset\",\"colorscale\",\"formula\",\"expression\",\"cellis\",\"topn\",\"top10\",\"top\",\"toppercent\",\"bottom\",\"bottompercent\",\"aboveaverage\",\"belowaverage\",\"uniquevalues\",\"duplicatevalues\",\"containstext\",\"dateoccurring\",\"timeperiod\",\"containsblanks\",\"notcontainsblanks\",\"containserrors\",\"notcontainserrors\",\"contains\",\"notcontains\",\"beginswith\",\"endswith\" };\nvar t = props.GetValueOrDefault(\"type\") ?? props.GetValueOrDefault(\"rule\");\nif (t != null && !CfTypes.Contains(t))\n    throw new ArgumentOutOfRangeException(\"type\", $\"Unknown CF type: {t}\");\nhandler.Add(\"/Sheet1\", \"conditionalformatting\", null, props);","typeGuard":"static bool IsKnownCfType(string? t) => t == null || CfTypes.Contains(t);","tryCatchPattern":null,"preventionTips":["Reuse the same allowlist constant used for the cf alias to keep both dispatch sites in sync.","Omit the type property to get the databar default for this alias.","Validate type/rule before Add to surface typos at the call site."],"tags":["excel","ooxml","conditional-formatting","databar","unknown-type","allowlist","argument"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}