grpc-ecosystem/grpc-gateway · error

can't map OpenAPI name from FQMN %q

Error message

can't map OpenAPI name from FQMN %q

What it means

lookupMsgAndOpenAPIName resolves a message reference for template rendering: it looks up the message in the registry and then maps its FQMN to an OpenAPI schema name. If reg.LookupMsg succeeds but fullyQualifiedNameToOpenAPIName fails, it returns 'can't map OpenAPI name from FQMN %q'. This mirrors error 108 but for a directly referenced message (e.g. a request/response type), meaning the message exists yet its OpenAPI name was never computed by the name-resolution pass.

Source

Thrown at protoc-gen-openapiv2/internal/genopenapi/template.go:1236

		ret, ok := mapping[fqn]
		return ret, ok
	}
	mapping := resolveFullyQualifiedNameToOpenAPINames(append(reg.GetAllFQMNs(), append(reg.GetAllFQENs(), reg.GetAllFQMethNs()...)...), reg.GetOpenAPINamingStrategy())
	registriesSeen[reg] = mapping
	ret, ok := mapping[fqn]
	return ret, ok
}

// Lookup message type by location.name and return an openapiv2-safe version
// of its FQMN.
func lookupMsgAndOpenAPIName(location, name string, reg *descriptor.Registry) (*descriptor.Message, string, error) {
	msg, err := reg.LookupMsg(location, name)
	if err != nil {
		return nil, "", err
	}
	swgName, ok := fullyQualifiedNameToOpenAPIName(msg.FQMN(), reg)
	if !ok {
		return nil, "", fmt.Errorf("can't map OpenAPI name from FQMN %q", msg.FQMN())
	}
	return msg, swgName, nil
}

// registriesSeen is used to memoise calls to resolveFullyQualifiedNameToOpenAPINames so
// we don't repeat it unnecessarily, since it can take some time.
var (
	registriesSeen      = map[*descriptor.Registry]map[string]string{}
	registriesSeenMutex sync.Mutex
)

// Take the names of every proto message and generate a unique reference for each, according to the given strategy.
func resolveFullyQualifiedNameToOpenAPINames(messages []string, namingStrategy string) map[string]string {
	strategyFn := LookupNamingStrategy(namingStrategy)
	if strategyFn == nil {
		return nil
	}
	return strategyFn(messages)

View on GitHub (pinned to a58a4436a3)

Solutions

  1. Run protoc-gen-openapiv2 over the complete set of protos (all dependencies) so every referenced FQMN is in the name map.
  2. Ensure consistent proto package declarations; fix collisions that break FQMN→OpenAPI-name mapping.
  3. Check the referenced message's package/name spelling in the RPC signature.
  4. Upgrade protoc-gen-openapiv2 to the latest release to pick up name-resolution fixes.

Example fix

// before: generating docs for service.proto only, response type from common.proto missing from name map
protoc --openapiv2_out=. service.proto
// after
protoc -I . --openapiv2_out=. service.proto common.proto
Defensive patterns

Strategy: validation

Validate before calling

// Before doc generation, confirm every RPC-referenced type maps to an OpenAPI name:
for _, svc := range services {
    for _, m := range svc.Methods {
        if _, ok := fullyQualifiedNameToOpenAPIName(m.RequestType.FQMN(), reg); !ok {
            return fmt.Errorf("request type %s unmapped; include its file in protoc", m.RequestType.FQMN())
        }
    }
}

Prevention

When it happens

Trigger: applyTemplate resolving a request/response or referenced message where reg.LookupMsg(location, name) succeeds but fullyQualifiedNameToOpenAPIName(msg.FQMN(), reg) returns false — the FQMN is absent from the resolved OpenAPI-name table built earlier in generation.

Common situations: RPC referencing messages from dependency protos whose name resolution was skipped or inconsistent (partial protoc invocation); package naming collisions affecting the uniquifier; custom naming/registry manipulations in plugins that bypass resolveFullyQualifiedNameToOpenAPINames.

Related errors


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