OrchardCMS/OrchardCore · error · ArgumentException

Invalid term in terms query

Error message

Invalid term in terms query

What it means

TermsFilterProvider.CreateFilteredQuery builds a Lucene terms filter from a JSON value. When the JSON value for the field is an array, every element must be a JSON string that becomes a TermQuery. This error is thrown when an element of the array is not a string (e.g. number, boolean, object, or null), because Lucene terms must be text.

Solutions

  1. Quote every element in the terms array as a JSON string (e.g. ["1", "2"] instead of [1, 2]).
  2. Validate the array client-side before sending, rejecting any non-string element.
  3. Catch ArgumentException around CreateFilteredQuery and return a 400 response with a clear message.

Example fix

// before
{"status": [1, 2]}
// after
{"status": ["1", "2"]}
Defensive patterns

Strategy: validation

Validate before calling

if (filter.Value.ValueKind != JsonValueKind.Array || filter.Value.EnumerateArray().Any(i => i.ValueKind != JsonValueKind.String))
    throw new ArgumentException("terms filter requires an array of JSON strings");

Type guard

static bool IsValidTermsFilter(JsonElement el) =>
    el.ValueKind == JsonValueKind.Array && el.EnumerateArray().All(i => i.ValueKind == JsonValueKind.String);

Try / catch

try { var query = provider.CreateFilteredQuery(context, filter); }
catch (ArgumentException ex) { return BadRequest($"Invalid terms filter: {ex.Message}"); }

Prevention

When it happens

Trigger: Calling CreateFilteredQuery with a filter JSON like {"field": [1, 2]} or {"field": ["a", true]} where any array element is a non-string JSON value.

Common situations: Client queries built from untyped user input or deserialized from a language that coerces numbers/booleans; copy-pasted Elasticsearch queries with numeric terms; hand-written JSON filters with accidental non-string entries.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/OrchardCore/OrchardCore.Lucene.Core/QueryProviders/Filters/TermsFilterProvider.cs:36

        {
            return null;
        }

        var queryObj = filter.AsObject();
        var first = queryObj.First();

        var field = first.Key;
        var boolQuery = new BooleanQuery();

        switch (first.Value.GetValueKind())
        {
            case JsonValueKind.Array:

                foreach (var item in first.Value.AsArray())
                {
                    if (item.GetValueKind() != JsonValueKind.String)
                    {
                        throw new ArgumentException($"Invalid term in terms query");
                    }

                    boolQuery.Add(new TermQuery(new Term(field, item.Value<string>())), Occur.SHOULD);
                }

                break;

            case JsonValueKind.Object:
                throw new ArgumentException("The terms lookup query is not supported");

            default: throw new ArgumentException("Invalid terms query");
        }

        booleanQuery.Add(boolQuery, Occur.MUST);
        var queryFilter = new QueryWrapperFilter(boolQuery);

        return new FilteredQuery(booleanQuery, queryFilter);
    }

View on GitHub (pinned to 4306c0717f)