iOfficeAI/OfficeCLI · error · System.ArgumentException

cellIs operator '{opStr}' requires 'value2' property (e.g. v

Error message

cellIs operator '{opStr}' requires 'value2' property (e.g. value=10 value2=50).

What it means

Thrown by AddCellIs when the operator is 'between' or 'notBetween' but no secondary operand is supplied. A between/notBetween comparison is binary (lower and upper bound), so the rule needs two <x:formula> children. The secondary value is read from 'value2', 'formula2', or 'maxvalue'.

Source

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

            "between" => ConditionalFormattingOperatorValues.Between,
            "notbetween" => ConditionalFormattingOperatorValues.NotBetween,
            _ => throw new ArgumentException(
                $"Unsupported cellIs operator '{opStr}'. Valid: greaterThan, lessThan, greaterThanOrEqual, lessThanOrEqual, equal, notEqual, between, notBetween.")
        };

        var primary = properties.GetValueOrDefault("value")
            ?? properties.GetValueOrDefault("formula")
            ?? properties.GetValueOrDefault("value1")
            ?? throw new ArgumentException("cellIs conditional formatting requires 'value' property (e.g. value=50).");
        var secondary = properties.GetValueOrDefault("value2")
            ?? properties.GetValueOrDefault("formula2")
            ?? properties.GetValueOrDefault("maxvalue");

        if ((opVal == ConditionalFormattingOperatorValues.Between
             || opVal == ConditionalFormattingOperatorValues.NotBetween)
            && secondary == null)
        {
            throw new ArgumentException(
                $"cellIs operator '{opStr}' requires 'value2' property (e.g. value=10 value2=50).");
        }

        // cellIs value/value2 land in <x:formula> (A1-only). Reject R1C1-style
        // refs so the file doesn't silently become one Excel refuses to open.
        ValidateNoR1C1Reference(primary);
        if (secondary != null) ValidateNoR1C1Reference(secondary);

        // Build DifferentialFormat (dxf)
        var cisDxf = new DifferentialFormat();
        if (properties.TryGetValue("font.color", out var cisFontColor))
        {
            var normalizedFontColor = ParseHelpers.NormalizeArgbColor(cisFontColor);
            cisDxf.Append(new Font(new DocumentFormat.OpenXml.Spreadsheet.Color { Rgb = normalizedFontColor }));
        }
        if (properties.TryGetValue("font.bold", out var cisFontBold) && IsTruthy(cisFontBold))
        {
            var existingFont = cisDxf.GetFirstChild<Font>();

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Supply the upper bound via value2, formula2, or maxvalue (e.g. value=10 value2=50).
  2. Switch to a unary operator (greaterThan, lessThan, equal, etc.) if only one bound is intended.
  3. Double-check the alias spelling — 'max=' is not accepted, use 'maxvalue='.

Example fix

// before: missing upper bound
add /Sheet1/A1:A10 cellis operator=between value=10
// after
add /Sheet1/A1:A10 cellis operator=between value=10 value2=50
Defensive patterns

Strategy: validation

Validate before calling

var op = (properties.GetValueOrDefault("operator") ?? "greaterThan").Trim().ToLowerInvariant();
var needsSecond = op is "between" or "notbetween";
var hasSecond = properties.ContainsKey("value2") || properties.ContainsKey("formula2") || properties.ContainsKey("maxvalue");
if (needsSecond && !hasSecond)
    throw new ArgumentException($"operator '{op}' requires value2/formula2/maxvalue.");

Type guard

static bool CellIsHasRequiredOperands(IReadOnlyDictionary<string,string> p)
{
    var op = (p.GetValueOrDefault("operator") ?? "greaterThan").Trim().ToLowerInvariant();
    if (op is not ("between" or "notbetween")) return true;
    return p.ContainsKey("value2") || p.ContainsKey("formula2") || p.ContainsKey("maxvalue");
}

Try / catch

try { return Add(path, "cellis", pos, props); }
catch (ArgumentException ex) when (ex.Message.Contains("requires 'value2'"))
{ /* prompt for upper bound, retry */ throw; }

Prevention

When it happens

Trigger: Calling Add with type=cellis operator=between (or notBetween), a primary value, but none of value2/formula2/maxvalue. Example: add /Sheet1/A1 cellis operator=between value=10 (missing upper bound).

Common situations: User assumes between defaults to an implicit upper bound; forgot the second property; used 'max=' instead of the accepted 'maxvalue=' alias.

Related errors


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