OrchardCMS/OrchardCore · error · ArgumentException

Invalid wildcard query

Error message

Invalid wildcard query

What it means

Despite its message, this throw is MatchPhraseFilterProvider's default switch branch: the match_phrase filter's value was neither a JSON object nor the accepted scalar form. The provider only supports Object (with "value"/"slop") and the other handled case; anything else hits default and throws ArgumentException("Invalid wildcard query").

Solutions

  1. Provide the phrase text as a string or as an object with a "value" string: {"match_phrase": {"Content": {"value": "phrase text"}}}.
  2. Move the slop option into the object form ({"value": ..., "slop": N}) instead of supplying a bare number.
  3. Validate the value's JsonValueKind (String or Object) before calling CreateFilteredQuery.
  4. If a wildcard query was actually intended, use the correct filter type (wildcard/match filter) rather than match_phrase.

Example fix

// before
{"match_phrase": {"Content": 42}}
// after
{"match_phrase": {"Content": {"value": "42", "slop": 0}}}
Defensive patterns

Strategy: validation

Validate before calling

if (filter.TryGetPropertyValue(field, out var v) &&
    v.ValueKind is not (JsonValueKind.String or JsonValueKind.Object))
{
    throw new InvalidOperationException(
        $"match_phrase value for '{field}' must be a string or object, got {v.ValueKind}.");
}

Type guard

static bool IsValidMatchPhraseValue(JsonElement v) =>
    v.ValueKind is JsonValueKind.String or JsonValueKind.Object;

Try / catch

try
{
    var query = provider.CreateFilteredQuery(context);
}
catch (ArgumentException ex) when (ex.Message.Contains("Invalid wildcard"))
{
    _logger.LogError(ex, "Unsupported match_phrase value kind: {Json}", filterJson);
    throw new QueryValidationException("match_phrase accepts only string or object values.", ex);
}

Prevention

When it happens

Trigger: Passing a match_phrase filter whose value is a JSON number, boolean, null, or nested array-of-objects — e.g. {"match_phrase": {"Content": 42}} or {"match_phrase": {"Content": [{"a":1}]}} — so the value kind falls through to the switch default.

Common situations: Malformed query JSON pasted from another search engine's DSL; a numeric value intended as slop placed where the phrase belongs; automated query generation emitting the wrong JSON type; copy-paste errors mixing up match_phrase with wildcard filter syntax.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

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

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

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

        return new FilteredQuery(booleanQuery, queryFilter);
    }
}

View on GitHub (pinned to 4306c0717f)