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

  1. Change the map key type to string (or a supported integral type) in the proto used for query parameters.
  2. Move the map out of the query request into a body-based (POST) request.
  3. Replace the map with repeated message entries (e.g. repeated Pair { string key; string value; }) which the generator can render.
  4. 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

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


AI-assisted analysis of grpc-ecosystem/grpc-gateway@a58a4436a3 (2026-09-02). Data as JSON: /api/errors/3f818392489680a1. Report an issue: GitHub.