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
- Convert the value to a supported primitive (ToString, explicit cast, or mapping) before passing.
- For enums, cast to int or convert to string.
- 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
- Map custom/enum types to primitives before building query strings.
- Add a test for each value type you persist in URLs.
- Pre-format complex values into strings at the call site.
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
- Cannot have empty query parameter names.
- Found malformed component comment at ${candidateStart.textCo
- descriptor must be defined when using a descriptor.
- sequence must be defined when using a descriptor.
- assembly must be defined when using a descriptor.
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/080cdc67e62b3661.
Report an issue: GitHub.