OrchardCMS/OrchardCore · error · ArgumentException

Unsupported range value type

Error message

Unsupported range value type: {type}

What it means

RangeFilterProvider.CreateFilteredQuery maps numeric range bounds to a Lucene NumericRangeQuery. It first tries long, then double; if the numeric bounds cannot be parsed as either, it throws ArgumentException($"Unsupported range value type: {type}") because the JSON number cannot be converted to a supported Lucene numeric range.

Solutions

  1. Supply plain, unit-free numeric literals for both bounds: {"gt": 10, "lt": 100} or with decimals {"gt": 10.5, "lt": 99.9}.
  2. If bounds carry units or currency, strip them and convert to a number before building the filter.
  3. For non-numeric (e.g. date) ranges, quote the bounds as strings so the string range path is used.
  4. Confirm the indexed field is numeric and the bound magnitudes fit in a double.

Example fix

// before
{"range": {"Weight": {"gt": "10kg", "lt": "20kg"}}}
// after
{"range": {"Weight": {"gt": 10, "lt": 20}}}
Defensive patterns

Strategy: validation

Validate before calling

if (gt.ValueKind == JsonValueKind.Number &&
    !(gt.TryGetInt64(out _) || gt.TryGetDouble(out _)))
{
    throw new InvalidOperationException($"Range bound '{gt}' is not a supported numeric type.");
}

Type guard

static bool IsSupportedNumericBound(JsonElement v) =>
    v.ValueKind == JsonValueKind.Number && (v.TryGetInt64(out _) || v.TryGetDouble(out _));

Try / catch

try
{
    var query = provider.CreateFilteredQuery(context);
}
catch (ArgumentException ex) when (ex.Message.StartsWith("Unsupported range value type"))
{
    _logger.LogError(ex, "Non-numeric range bound for numeric field: {Json}", filterJson);
    throw new QueryValidationException("Numeric range bounds must parse as long or double.", ex);
}

Prevention

When it happens

Trigger: Passing a numeric range where bounds are JSON numbers not representable as long or double — e.g. decimal strings with unit suffixes ("10kg"), or a value kind typed as Number but holding content that fails both TryGetValue<long> and TryGetValue<double> conversions (such as extremely large values or numbers supplied via GetRawText quirks).

Common situations: Bounds containing currency symbols or units ("$10"); locale-formatted numbers with comma decimal separators; a decimal bound exceeding double precision handling; query JSON produced by code writing decimals in a form System.Text.Json won't convert to long/double.

Related errors


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

Appendix: source

Thrown at src/OrchardCore/OrchardCore.Lucene.Core/QueryProviders/Filters/RangeFilterProvider.cs:86

                    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}");
                        }

                        break;

                    case JsonValueKind.String:
                        var minString = gt?.Value<string>();
                        var maxString = lt?.Value<string>();
                        rangeQuery = TermRangeQuery.NewStringRange(field, minString, maxString, includeLower, includeUpper);
                        break;

                    default: throw new ArgumentException($"Unsupported range value type: {type}");
                }

                if (boost != null)
                {
                    rangeQuery.Boost = boost.Value;
                }

View on GitHub (pinned to 4306c0717f)