OrchardCMS/OrchardCore · error · ArgumentException

Lower and upper bound range types don't match

Error message

Lower and upper bound range types don't match

What it means

RangeQueryProvider.CreateQuery supports range queries where the lower (gt/gte) and upper (lt/lte) bounds are of the same JSON type (both numbers or both strings). If both bounds are present but their JSON value kinds differ, e.g. a number lower bound with a string upper bound, it throws ArgumentException because Lucene range queries need homogeneous bound types.

Solutions

  1. Make both bounds the same JSON type — quote both or unquote both, e.g. {"gt": "5", "lt": "10"} or {"gt": 5, "lt": 10}.
  2. If the field is a date/text field, express both bounds as strings; if numeric, both as numbers.
  3. Normalize bound values in the code that assembles the query before calling CreateQuery.

Example fix

// before
{"Price": {"type": "range", "gt": 10, "lt": "100"}}
// after
{"Price": {"type": "range", "gt": 10, "lt": 100}}
Defensive patterns

Strategy: validation

Validate before calling

var gt = obj["gt"] ?? obj["gte"]; var lt = obj["lt"] ?? obj["lte"]; if (gt != null && lt != null && gt.GetValueKind() != lt.GetValueKind()) throw new InvalidOperationException("Range bounds must share the same JSON type");

Type guard

static bool BoundsKindMatch(JsonNode obj) { var g = obj["gt"] ?? obj["gte"]; var l = obj["lt"] ?? obj["lte"]; return g == null || l == null || g.GetValueKind() == l.GetValueKind(); }

Try / catch

try { var q = provider.CreateQuery(node); } catch (ArgumentException ex) when (ex.Message.Contains("range types don't match")) { // coerce both bounds to a common type and retry }

Prevention

When it happens

Trigger: A range node like {"field": {"type": "range", "gt": 5, "lt": "10"}} — gt is a number but lt is a string, so GetValueKind() differs.

Common situations: Mixing quoted and unquoted numbers in hand-edited query JSON; dates given as strings with numeric bounds; query built by concatenating user-supplied filters of different types.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/5aa7f76776eaeaa1. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore/OrchardCore.Lucene.Core/QueryProviders/RangeQueryProvider.cs:61

                            break;
                        case "lt":
                            lt = element.Value;
                            nodeKind = lt.GetValueKind();
                            break;
                        case "lte":
                            lt = element.Value;
                            nodeKind = lt.GetValueKind();
                            includeUpper = true;
                            break;
                        case "boost":
                            boost = element.Value.Value<float>();
                            break;
                    }
                }

                if (gt != null && lt != null && gt.GetValueKind() != lt.GetValueKind())
                {
                    throw new ArgumentException("Lower and upper bound range types don't match");
                }

                switch (nodeKind)
                {
                    case JsonValueKind.Number:
                        if (gt.AsValue().TryGetValue<long>(out var minInt) &&
                            lt.AsValue().TryGetValue<long>(out var maxInt))
                        {
                            rangeQuery = NumericRangeQuery.NewInt64Range(field, minInt, maxInt, includeLower, includeUpper);
                        }
                        else if (gt.AsValue().TryGetValue<double>(out var minFloat) &&
                            lt.AsValue().TryGetValue<double>(out var maxFloat))
                        {
                            rangeQuery = NumericRangeQuery.NewDoubleRange(field, minFloat, maxFloat, includeLower, includeUpper);
                        }
                        else
                        {
                            throw new ArgumentException($"Unsupported range value type: {type}");

View on GitHub (pinned to 4306c0717f)