dotnet/aspnetcore · error · InvalidOperationException

Cannot format query parameters with values of type '{underly

Error message

Cannot format query parameters with values of type '{underlyingParameterValueType}'.

What it means

GetFormatterFromParameterValueType throws InvalidOperationException when the value type passed to a query parameter is not one of the supported primitive types (string, bool, DateTime, DateOnly, TimeOnly, decimal, double, float, Guid, int, long). The formatter dictionary has no entry for that type, so serialization cannot proceed.

Source

Thrown at src/Components/Components/src/NavigationManagerExtensions.cs:723

    {
        var parameterSources = new Dictionary<ReadOnlyMemory<char>, QueryParameterSource>(QueryParameterNameComparer.Instance);

        foreach (var (name, value) in parameters)
        {
            var parameterSource = new QueryParameterSource(name, value);
            parameterSources.Add(parameterSource.EncodedName.AsMemory(), parameterSource);
        }

        return parameterSources;
    }

    private static QueryParameterFormatter<object> GetFormatterFromParameterValueType(Type parameterValueType)
    {
        var underlyingParameterValueType = Nullable.GetUnderlyingType(parameterValueType) ?? parameterValueType;

        if (!_queryParameterFormatters.TryGetValue(underlyingParameterValueType, out var formatter))
        {
            throw new InvalidOperationException(
                $"Cannot format query parameters with values of type '{underlyingParameterValueType}'.");
        }

        return formatter;
    }

    private static bool TryRebuildExistingQueryFromUri(
        string uri,
        out QueryStringEnumerable existingQueryStringEnumerable,
        out ReadOnlySpan<char> hash,
        out QueryStringBuilder newQueryStringBuilder)
    {
        ReadOnlySpan<char> uriWithoutQueryStringAndHash;

        var hashStartIndex = uri.IndexOf('#');
        hash = hashStartIndex < 0 ? "" : uri.AsSpan(hashStartIndex);

        var queryStartIndex = (hashStartIndex > 0 ? uri.AsSpan(0, hashStartIndex) : uri).IndexOf('?');

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Convert the value to a supported primitive (ToString, explicit cast, or mapping) before passing.
  2. For enums, cast to int or convert to string.
  3. Use GetUriWithQueryParameter(string, string?) and pre-format the value yourself.

Example fix

// before
var qs = navManager.GetUriWithQueryParameters(new Dictionary<string,object?> { ["status"] = myEnum });

// after
var qs = navManager.GetUriWithQueryParameters(new Dictionary<string,object?> { ["status"] = (int)myEnum });
Defensive patterns

Strategy: validation

Validate before calling

static readonly HashSet<Type> Supported = new()
{ typeof(string), typeof(bool), typeof(DateTime), typeof(DateOnly), typeof(TimeOnly),
  typeof(decimal), typeof(double), typeof(float), typeof(Guid), typeof(int), typeof(long) };

static object? ConvertForQuery(object? v) => v switch
{
    Enum e => (int)(object)e,
    not null when !Supported.Contains(Nullable.GetUnderlyingType(v.GetType()) ?? v.GetType()) => v.ToString(),
    _ => v
};

Type guard

static bool IsSupportedQueryType(Type t)
{
    var u = Nullable.GetUnderlyingType(t) ?? t;
    return u == typeof(string) || u == typeof(bool) || u == typeof(DateTime) ||
           u == typeof(DateOnly) || u == typeof(TimeOnly) || u == typeof(decimal) ||
           u == typeof(double) || u == typeof(float) || u == typeof(Guid) ||
           u == typeof(int) || u == typeof(long);
}

Try / catch

try { uri = navManager.GetUriWithQueryParameters(parameters); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Cannot format query parameters"))
{ logger.LogWarning(ex, "Unsupported type; converting to string");
  uri = navManager.GetUriWithQueryParameters(parameters.ToDictionary(p => p.Key, p => (object?)p.Value?.ToString())); }

Prevention

When it happens

Trigger: Passing an object/struct of an unsupported type (e.g. enum, custom struct, complex object, uint, byte) as a query parameter value via GetUriWithQueryParameters; passing a nullable whose underlying type is unsupported; passing an array/IEnumerable of an unsupported element type.

Common situations: Binding a model with enum or custom-type properties directly into query parameters; passing DTOs instead of primitives; version differences that add new value types not yet mapped.

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/080cdc67e62b3661. Report an issue: GitHub.