grpc-ecosystem/grpc-gateway · error
%s: missing required field "openapi"
Error message
%s: missing required field "openapi"
What it means
Raised in parse() when a document's top-level object has no "openapi" string field (or it is empty). OpenAPI 3.1 requires the "openapi" version field, so this library refuses to merge a document that omits it. The message names the offending input document.
Source
Thrown at openapiv3-merge/internal/merge/merge.go:248
case "security":
if err := json.Unmarshal(raw, &d.Security); err != nil {
return nil, fmt.Errorf("%s: security: %w", in.Name, err)
}
case "tags":
if err := json.Unmarshal(raw, &d.Tags); err != nil {
return nil, fmt.Errorf("%s: tags: %w", in.Name, err)
}
case "externalDocs":
d.ExternalDocs = raw
default:
d.extras.set(key, raw)
}
}
if _, err := dec.Token(); err != nil {
return nil, fmt.Errorf("%s: %w", in.Name, err)
}
if d.OpenAPI == "" {
return nil, fmt.Errorf("%s: missing required field \"openapi\"", in.Name)
}
if isJSONNull(d.Info) {
return nil, fmt.Errorf("%s: missing required field \"info\"", in.Name)
}
return d, nil
}
// mergeAll merges parsed documents in order. The first establishes the
// values that later inputs must not contradict.
func mergeAll(docs []*document) (*document, error) {
first := docs[0]
out := &document{
name: "merged",
OpenAPI: first.OpenAPI,
Info: first.Info,
Servers: first.Servers,
Paths: newOrderedObject(),
Webhooks: newOrderedObject(),View on GitHub (pinned to a58a4436a3)
Solutions
- Add a top-level "openapi" field with a valid version string (e.g. "3.1.0") to the named document
- If the file is Swagger 2.0, migrate it to OpenAPI 3.x first
- Regenerate the document with the generator's version flag enabled
- Verify you are passing the full document, not a sub-object
Example fix
// before
{ "info": { "title": "api" }, "paths": {} }
// after
{ "openapi": "3.1.0", "info": { "title": "api" }, "paths": {} } Defensive patterns
Strategy: validation
Validate before calling
func hasOpenAPIField(data []byte) error {
var doc struct { OpenAPI string `json:"openapi"` }
if err := json.Unmarshal(data, &doc); err != nil { return err }
if doc.OpenAPI == "" { return errors.New("missing required field \"openapi\"") }
if !strings.HasPrefix(doc.OpenAPI, "3.") { return fmt.Errorf("unsupported version %q", doc.OpenAPI) }
return nil
} Type guard
func isOpenAPI3(data []byte) bool {
var doc struct { OpenAPI string `json:"openapi"` }
return json.Unmarshal(data, &doc) == nil && strings.HasPrefix(doc.OpenAPI, "3.1")
} Try / catch
if err := hasOpenAPIField(in.Data); err != nil {
return fmt.Errorf("input %s rejected: %w", in.Name, err)
}
merged, err := merge.Merge(inputs) Prevention
- Always include "openapi": "3.1.0" in generated documents
- Reject Swagger 2.0 files ("swagger" key) before merging
- Add schema validation of each input in CI before merge
- Do not strip top-level fields when extracting fragments
When it happens
Trigger: Calling Merge with an Input whose Data is a JSON object lacking a top-level "openapi": "3.1.x" field — e.g. a Swagger 2.0 doc using "swagger", an OpenAPI fragment, or an empty object {}.
Common situations: Merging a Swagger 2.0 file (key is "swagger", not "openapi"), generator output with the version stripped, hand-written stubs missing the field, or a fragment extracted from a larger document.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- %s: missing required field "info"
- %s: expected JSON object at top level
- unexpected number of yaml nodes
- only primitive and enum types are allowed in repeated path p
- only primitive and well-known types are allowed in path para
AI-assisted analysis of grpc-ecosystem/grpc-gateway@a58a4436a3 (2026-09-02).
Data as JSON: /api/errors/ecf18c6ce9b82d0b.
Report an issue: GitHub.