{"record":{"id":"b31dc04a50d8f1fa","repo":"iOfficeAI/OfficeCLI","slug":"unsupported-cellis-operator-opstr-valid-grea","errorCode":null,"errorMessage":"Unsupported cellIs operator '{opStr}'. Valid: greaterThan, lessThan, greaterThanOrEqual, lessThanOrEqual, equal, notEqual, between, notBetween.","messagePattern":"Unsupported cellIs operator '(.+?)'\\. Valid: greaterThan, lessThan, greaterThanOrEqual, lessThanOrEqual, equal, notEqual, between, notBetween\\.","errorType":"validation","errorClass":"System.ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Cf.cs","lineNumber":539,"sourceCode":"\n        // CONSISTENCY(cf-sqref): three-level fallback matches dataBar/colorScale branches.\n        // R22-2: path-tail range is the fallback before the hardcoded default.\n        var cisPathRange = cisSegments.Length > 1 && !string.IsNullOrEmpty(cisSegments[1]) ? cisSegments[1] : \"A1:A10\";\n        var cisSqref = ValidateSqref(properties.GetValueOrDefault(\"sqref\")\n            ?? properties.GetValueOrDefault(\"range\")\n            ?? properties.GetValueOrDefault(\"ref\", cisPathRange), \"ref\");\n        var opStr = (properties.GetValueOrDefault(\"operator\") ?? \"greaterThan\").Trim();\n        var opVal = opStr.ToLowerInvariant() switch\n        {\n            \"greaterthan\" or \"gt\" or \">\" => ConditionalFormattingOperatorValues.GreaterThan,\n            \"lessthan\" or \"lt\" or \"<\" => ConditionalFormattingOperatorValues.LessThan,\n            \"greaterthanorequal\" or \"gte\" or \">=\" => ConditionalFormattingOperatorValues.GreaterThanOrEqual,\n            \"lessthanorequal\" or \"lte\" or \"<=\" => ConditionalFormattingOperatorValues.LessThanOrEqual,\n            \"equal\" or \"eq\" or \"=\" or \"==\" => ConditionalFormattingOperatorValues.Equal,\n            \"notequal\" or \"ne\" or \"!=\" or \"<>\" => ConditionalFormattingOperatorValues.NotEqual,\n            \"between\" => ConditionalFormattingOperatorValues.Between,\n            \"notbetween\" => ConditionalFormattingOperatorValues.NotBetween,\n            _ => throw new ArgumentException(\n                $\"Unsupported cellIs operator '{opStr}'. Valid: greaterThan, lessThan, greaterThanOrEqual, lessThanOrEqual, equal, notEqual, between, notBetween.\")\n        };\n\n        var primary = properties.GetValueOrDefault(\"value\")\n            ?? properties.GetValueOrDefault(\"formula\")\n            ?? properties.GetValueOrDefault(\"value1\")\n            ?? throw new ArgumentException(\"cellIs conditional formatting requires 'value' property (e.g. value=50).\");\n        var secondary = properties.GetValueOrDefault(\"value2\")\n            ?? properties.GetValueOrDefault(\"formula2\")\n            ?? properties.GetValueOrDefault(\"maxvalue\");\n\n        if ((opVal == ConditionalFormattingOperatorValues.Between\n             || opVal == ConditionalFormattingOperatorValues.NotBetween)\n            && secondary == null)\n        {\n            throw new ArgumentException(\n                $\"cellIs operator '{opStr}' requires 'value2' property (e.g. value=10 value2=50).\");\n        }","sourceCodeStart":521,"sourceCodeEnd":557,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Cf.cs#L521-L557","documentation":"Thrown by AddCellIs when the 'operator' property (default 'greaterThan') lowercases to a value not in the supported operator set. The operator drives the OOXML ConditionalFormattingOperatorValues enum and determines how many formula operands are required. Rejecting an unknown operator prevents emitting an invalid cfRule and avoids silent miscategorization.","triggerScenarios":"Calling Add with type=cellis and operator=<x> where x is not one of: greaterThan/gt/>, lessThan/lt/<, greaterThanOrEqual/gte/>=, lessThanOrEqual/lte/<=, equal/eq/=/==, notEqual/ne/!=/<>, between, notBetween. Example: operator=contains, operator=>>.","commonSituations":"Typing a text-operator name (contains/beginsWith) into a cellIs rule instead of a comparison; using a symbol form not in the alias list; locale capitalization (handled, but a genuinely wrong word is not).","solutions":["Use a supported operator name or symbol alias (see message for the full list).","For text-matching rules (contains/beginsWith/endsWith), use the cfextended path (type=containsText/beginsWith/endsWith), not cellIs.","Omit operator to accept the default 'greaterThan'."],"exampleFix":"// before: operator=contains (wrong for cellIs)\nadd /Sheet1/A1:A10 cellis operator=contains value=50\n// after: comparison operator\nadd /Sheet1/A1:A10 cellis operator=equal value=50","handlingStrategy":"validation","validationCode":"var ops = new HashSet<string>(StringComparer.OrdinalIgnoreCase)\n{ \"greaterThan\",\"gt\",\">\",\"lessThan\",\"lt\",\"<\",\"greaterThanOrEqual\",\"gte\",\">=\",\n  \"lessThanOrEqual\",\"lte\",\"<=\",\"equal\",\"eq\",\"=\",\"==\",\"notEqual\",\"ne\",\"!=\",\"<>\",\"between\",\"notBetween\" };\nvar op = (properties.GetValueOrDefault(\"operator\") ?? \"greaterThan\").Trim();\nif (!ops.Contains(op)) throw new ArgumentException($\"operator '{op}' invalid.\");","typeGuard":"static readonly HashSet<string> CellIsOperators = new(StringComparer.OrdinalIgnoreCase)\n{ \"greaterThan\",\"gt\",\">\",\"lessThan\",\"lt\",\"<\",\"greaterThanOrEqual\",\"gte\",\">=\",\n  \"lessThanOrEqual\",\"lte\",\"<=\",\"equal\",\"eq\",\"=\",\"==\",\"notEqual\",\"ne\",\"!=\",\"<>\",\"between\",\"notBetween\" };\nstatic bool IsValidCellIsOperator(string? s) => s is null || CellIsOperators.Contains(s);","tryCatchPattern":"try { return Add(path, \"cellis\", pos, props); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"cellIs operator\"))\n{ props[\"operator\"] = \"equal\"; return Add(path, \"cellis\", pos, props); }","preventionTips":["Whitelist the operator against the comparison set before calling Add.","Use text-match types (containsText/beginsWith) for text rules, not cellIs.","Omit operator to accept the default 'greaterThan'."],"tags":["excel","conditional-formatting","cellis","enum-validation","argument-validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}