grpc-ecosystem/grpc-gateway · error
unsupported type: %q
Error message
unsupported type: %q
What it means
getMapParamKey derives the OpenAPI parameter key type for map-typed query fields. OpenAPI query parameter map keys must be simple string-renderable primitive types; if the key field's type is not a supported primitive (or is byte/float/double), the generator refuses with 'unsupported type: %q'. Protobuf allows int32/bool etc. as map keys, but this generator can't express such keys as flat query parameters.
Source
Thrown at protoc-gen-openapiv2/internal/genopenapi/template.go:480
for _, nestedField := range msg.Fields {
if !isVisible(getFieldVisibilityOption(nestedField), reg) {
continue
}
fieldName := reg.FieldName(field)
p, err := nestedQueryParams(msg, nestedField, prefix+fieldName+".", reg, pathParams, body, touchedOut)
if err != nil {
return nil, err
}
params = append(params, p...)
}
return params, nil
}
func getMapParamKey(t descriptorpb.FieldDescriptorProto_Type) (string, error) {
tType, f, ok := primitiveSchema(t)
if !ok || f == "byte" || f == "float" || f == "double" {
return "", fmt.Errorf("unsupported type: %q", f)
}
return tType, nil
}
// findServicesMessagesAndEnumerations discovers all messages and enums defined in the RPC methods of the service.
func findServicesMessagesAndEnumerations(s []*descriptor.Service, reg *descriptor.Registry, m messageMap, ms messageMap, e enumMap, refs refMap) {
for _, svc := range s {
if !isVisible(getServiceVisibilityOption(svc), reg) {
continue
}
for _, meth := range svc.Methods {
// Request may be fully included in query
{
if !isVisible(getMethodVisibilityOption(meth), reg) {
continue
}
View on GitHub (pinned to a58a4436a3)
Solutions
- Change the map key type to string (or a supported integral type) in the proto used for query parameters.
- Move the map out of the query request into a body-based (POST) request.
- Replace the map with repeated message entries (e.g. repeated Pair { string key; string value; }) which the generator can render.
- If the key must remain non-string, exclude that field from query rendering by restructuring the request message.
Example fix
// before
message GetRequest { map<int64, string> attrs = 1; }
// after
message GetRequest { map<string, string> attrs = 1; } Defensive patterns
Strategy: validation
Validate before calling
// Pre-check map key types in query request protos:
if keyType == "bytes" || keyType == "float" || keyType == "double" {
return fmt.Errorf("map key type %s unsupported for query params; use string", keyType)
} Prevention
- Convention: always use string keys for maps in GET request messages.
- Prefer repeated key/value message pairs over exotic map key types.
- Document the constraint in proto style guide for the team.
When it happens
Trigger: nestedQueryParams encounters a map field whose key type t, passed through primitiveSchema, is either not a primitive (ok=false) or maps to byte, float, or double — i.e. a map<k,v> in a query parameter path with an unsupported key type k.
Common situations: Protos using map<int64, string> or map<bool, ...> in GET request messages rendered as query parameters; maps keyed by bytes; legacy protos with unusual key choices surfaced when first generating OpenAPI docs.
Related errors
- failed to encode OpenAPI for %s: %w
- unknown enum type %s
- unknown message type %s
- exceeded recursive count (%d) for query parameter %q
- can't resolve OpenAPI name from %q
AI-assisted analysis of grpc-ecosystem/grpc-gateway@a58a4436a3 (2026-09-02).
Data as JSON: /api/errors/3f818392489680a1.
Report an issue: GitHub.