{"record":{"id":"ed532b36ee2a954b","repo":"OrchardCMS/OrchardCore","slug":"missing-value-in-match-phrase-query","errorCode":null,"errorMessage":"Missing value in match phrase query","messagePattern":"Missing value in match phrase query","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore/OrchardCore.Lucene.Core/QueryProviders/Filters/MatchPhraseFilterProvider.cs","lineNumber":38,"sourceCode":"        }\n\n        var queryObj = filter.AsObject();\n        var first = queryObj.First();\n\n        var phraseQuery = new PhraseQuery();\n        JsonNode value;\n\n        switch (first.Value.GetValueKind())\n        {\n            case JsonValueKind.String:\n                value = first.Value;\n                break;\n            case JsonValueKind.Object:\n                var obj = first.Value.AsObject();\n\n                if (!obj.TryGetPropertyValue(\"value\", out value))\n                {\n                    throw new ArgumentException(\"Missing value in match phrase query\");\n                }\n\n                // TODO: read \"analyzer\" property\n\n                if (obj.TryGetPropertyValue(\"slop\", out var slop))\n                {\n                    phraseQuery.Slop = slop.Value<int>();\n                }\n\n                break;\n            default: throw new ArgumentException(\"Invalid wildcard query\");\n        }\n\n        foreach (var term in LuceneQueryService.Tokenize(first.Key, value.Value<string>(), context.DefaultAnalyzer))\n        {\n            phraseQuery.Add(new Term(first.Key, term));\n        }\n","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore.Lucene.Core/QueryProviders/Filters/MatchPhraseFilterProvider.cs#L20-L56","documentation":"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.","triggerScenarios":"Calling CreateFilteredQuery with a filter like {\"match_phrase\": {\"Content\": {\"slop\": 2}}} — an object that sets options (slop, boost) but omits the mandatory \"value\" property.","commonSituations":"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.","solutions":["Add the required \"value\" property to the match_phrase object: {\"match_phrase\": {\"Content\": {\"value\": \"exact phrase\", \"slop\": 2}}}.","Alternatively pass the phrase as a plain string value: {\"match_phrase\": {\"Content\": \"exact phrase\"}}.","Validate that every match_phrase object has a non-empty \"value\" key before executing the query.","Check saved recipes/queries for match_phrase filters whose value was removed during editing or migration."],"exampleFix":"// before\n{\"match_phrase\": {\"Content\": {\"slop\": 2}}}\n// after\n{\"match_phrase\": {\"Content\": {\"value\": \"red car\", \"slop\": 2}}}","handlingStrategy":"validation","validationCode":"if (filter.TryGetPropertyValue(field, out var v) && v.ValueKind == JsonValueKind.Object &&\n    !v.AsObject().TryGetPropertyValue(\"value\", out var val) ||\n    (val.ValueKind == JsonValueKind.String && string.IsNullOrWhiteSpace(val.GetString())))\n{\n    throw new InvalidOperationException($\"match_phrase filter for '{field}' requires a non-empty 'value'.\");\n}","typeGuard":"static bool HasMatchPhraseValue(JsonElement v) =>\n    v.ValueKind != JsonValueKind.Object ||\n    v.AsObject().TryGetPropertyValue(\"value\", out _);","tryCatchPattern":"try\n{\n    var query = provider.CreateFilteredQuery(context);\n}\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Missing value\"))\n{\n    _logger.LogError(ex, \"match_phrase filter without 'value': {Json}\", filterJson);\n    throw new QueryValidationException(\"match_phrase requires a 'value' property.\", ex);\n}","preventionTips":["Treat \"value\" as mandatory whenever a match_phrase filter uses the object form.","Keep options (slop, boost) together with a present \"value\" key.","Add schema validation of query JSON at save time in the admin UI."],"tags":["lucene","query-filter","missing-value","json"],"backgroundTag":"missing-required-argument","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}