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

  1. Add a top-level "openapi" field with a valid version string (e.g. "3.1.0") to the named document
  2. If the file is Swagger 2.0, migrate it to OpenAPI 3.x first
  3. Regenerate the document with the generator's version flag enabled
  4. 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

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


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