{"record":{"id":"080cdc67e62b3661","repo":"dotnet/aspnetcore","slug":"cannot-format-query-parameters-with-values-of-type","errorCode":null,"errorMessage":"Cannot format query parameters with values of type '{underlyingParameterValueType}'.","messagePattern":"Cannot format query parameters with values of type '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/NavigationManagerExtensions.cs","lineNumber":723,"sourceCode":"    {\n        var parameterSources = new Dictionary<ReadOnlyMemory<char>, QueryParameterSource>(QueryParameterNameComparer.Instance);\n\n        foreach (var (name, value) in parameters)\n        {\n            var parameterSource = new QueryParameterSource(name, value);\n            parameterSources.Add(parameterSource.EncodedName.AsMemory(), parameterSource);\n        }\n\n        return parameterSources;\n    }\n\n    private static QueryParameterFormatter<object> GetFormatterFromParameterValueType(Type parameterValueType)\n    {\n        var underlyingParameterValueType = Nullable.GetUnderlyingType(parameterValueType) ?? parameterValueType;\n\n        if (!_queryParameterFormatters.TryGetValue(underlyingParameterValueType, out var formatter))\n        {\n            throw new InvalidOperationException(\n                $\"Cannot format query parameters with values of type '{underlyingParameterValueType}'.\");\n        }\n\n        return formatter;\n    }\n\n    private static bool TryRebuildExistingQueryFromUri(\n        string uri,\n        out QueryStringEnumerable existingQueryStringEnumerable,\n        out ReadOnlySpan<char> hash,\n        out QueryStringBuilder newQueryStringBuilder)\n    {\n        ReadOnlySpan<char> uriWithoutQueryStringAndHash;\n\n        var hashStartIndex = uri.IndexOf('#');\n        hash = hashStartIndex < 0 ? \"\" : uri.AsSpan(hashStartIndex);\n\n        var queryStartIndex = (hashStartIndex > 0 ? uri.AsSpan(0, hashStartIndex) : uri).IndexOf('?');","sourceCodeStart":705,"sourceCodeEnd":741,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Components/src/NavigationManagerExtensions.cs#L705-L741","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nvar qs = navManager.GetUriWithQueryParameters(new Dictionary<string,object?> { [\"status\"] = myEnum });\n\n// after\nvar qs = navManager.GetUriWithQueryParameters(new Dictionary<string,object?> { [\"status\"] = (int)myEnum });","handlingStrategy":"validation","validationCode":"static readonly HashSet<Type> Supported = new()\n{ typeof(string), typeof(bool), typeof(DateTime), typeof(DateOnly), typeof(TimeOnly),\n  typeof(decimal), typeof(double), typeof(float), typeof(Guid), typeof(int), typeof(long) };\n\nstatic object? ConvertForQuery(object? v) => v switch\n{\n    Enum e => (int)(object)e,\n    not null when !Supported.Contains(Nullable.GetUnderlyingType(v.GetType()) ?? v.GetType()) => v.ToString(),\n    _ => v\n};","typeGuard":"static bool IsSupportedQueryType(Type t)\n{\n    var u = Nullable.GetUnderlyingType(t) ?? t;\n    return u == typeof(string) || u == typeof(bool) || u == typeof(DateTime) ||\n           u == typeof(DateOnly) || u == typeof(TimeOnly) || u == typeof(decimal) ||\n           u == typeof(double) || u == typeof(float) || u == typeof(Guid) ||\n           u == typeof(int) || u == typeof(long);\n}","tryCatchPattern":"try { uri = navManager.GetUriWithQueryParameters(parameters); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Cannot format query parameters\"))\n{ logger.LogWarning(ex, \"Unsupported type; converting to string\");\n  uri = navManager.GetUriWithQueryParameters(parameters.ToDictionary(p => p.Key, p => (object?)p.Value?.ToString())); }","preventionTips":["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."],"tags":["blazor","query-string","type-validation","serialization","navigation"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}