OrchardCMS/OrchardCore · error · ArgumentException

Missing value in match phrase query

Error message

Missing value in match phrase query

What it means

MatchPhraseFilterProvider.CreateFilteredQuery requires a match_phrase filter whose value is a JSON object containing a "value" property. When the value is an object but has no "value" key, the provider throws ArgumentException("Missing value in match phrase query") because it has no text to build the PhraseQuery from.

Solutions

  1. Add the required "value" property to the match_phrase object: {"match_phrase": {"Content": {"value": "exact phrase", "slop": 2}}}.
  2. Alternatively pass the phrase as a plain string value: {"match_phrase": {"Content": "exact phrase"}}.
  3. Validate that every match_phrase object has a non-empty "value" key before executing the query.
  4. Check saved recipes/queries for match_phrase filters whose value was removed during editing or migration.

Example fix

// before
{"match_phrase": {"Content": {"slop": 2}}}
// after
{"match_phrase": {"Content": {"value": "red car", "slop": 2}}}
Defensive patterns

Strategy: validation

Validate before calling

if (filter.TryGetPropertyValue(field, out var v) && v.ValueKind == JsonValueKind.Object &&
    !v.AsObject().TryGetPropertyValue("value", out var val) ||
    (val.ValueKind == JsonValueKind.String && string.IsNullOrWhiteSpace(val.GetString())))
{
    throw new InvalidOperationException($"match_phrase filter for '{field}' requires a non-empty 'value'.");
}

Type guard

static bool HasMatchPhraseValue(JsonElement v) =>
    v.ValueKind != JsonValueKind.Object ||
    v.AsObject().TryGetPropertyValue("value", out _);

Try / catch

try
{
    var query = provider.CreateFilteredQuery(context);
}
catch (ArgumentException ex) when (ex.Message.Contains("Missing value"))
{
    _logger.LogError(ex, "match_phrase filter without 'value': {Json}", filterJson);
    throw new QueryValidationException("match_phrase requires a 'value' property.", ex);
}

Prevention

When it happens

Trigger: Calling CreateFilteredQuery with a filter like {"match_phrase": {"Content": {"slop": 2}}} — an object that sets options (slop, boost) but omits the mandatory "value" property.

Common situations: Copying an Elasticsearch-style match_phrase clause where the value is the bare phrase string; hand-editing a saved query and deleting the value line while leaving options; generating filter JSON programmatically with an empty/omitted value field.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/OrchardCore/OrchardCore.Lucene.Core/QueryProviders/Filters/MatchPhraseFilterProvider.cs:38

        }

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

        var phraseQuery = new PhraseQuery();
        JsonNode value;

        switch (first.Value.GetValueKind())
        {
            case JsonValueKind.String:
                value = first.Value;
                break;
            case JsonValueKind.Object:
                var obj = first.Value.AsObject();

                if (!obj.TryGetPropertyValue("value", out value))
                {
                    throw new ArgumentException("Missing value in match phrase query");
                }

                // TODO: read "analyzer" property

                if (obj.TryGetPropertyValue("slop", out var slop))
                {
                    phraseQuery.Slop = slop.Value<int>();
                }

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

        foreach (var term in LuceneQueryService.Tokenize(first.Key, value.Value<string>(), context.DefaultAnalyzer))
        {
            phraseQuery.Add(new Term(first.Key, term));
        }

View on GitHub (pinned to 4306c0717f)