{"record":{"id":"ecf18c6ce9b82d0b","repo":"grpc-ecosystem/grpc-gateway","slug":"s-missing-required-field-openapi","errorCode":null,"errorMessage":"%s: missing required field \"openapi\"","messagePattern":"(.+?): missing required field \"openapi\"","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"openapiv3-merge/internal/merge/merge.go","lineNumber":248,"sourceCode":"\t\tcase \"security\":\n\t\t\tif err := json.Unmarshal(raw, &d.Security); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"%s: security: %w\", in.Name, err)\n\t\t\t}\n\t\tcase \"tags\":\n\t\t\tif err := json.Unmarshal(raw, &d.Tags); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"%s: tags: %w\", in.Name, err)\n\t\t\t}\n\t\tcase \"externalDocs\":\n\t\t\td.ExternalDocs = raw\n\t\tdefault:\n\t\t\td.extras.set(key, raw)\n\t\t}\n\t}\n\tif _, err := dec.Token(); err != nil {\n\t\treturn nil, fmt.Errorf(\"%s: %w\", in.Name, err)\n\t}\n\tif d.OpenAPI == \"\" {\n\t\treturn nil, fmt.Errorf(\"%s: missing required field \\\"openapi\\\"\", in.Name)\n\t}\n\tif isJSONNull(d.Info) {\n\t\treturn nil, fmt.Errorf(\"%s: missing required field \\\"info\\\"\", in.Name)\n\t}\n\treturn d, nil\n}\n\n// mergeAll merges parsed documents in order. The first establishes the\n// values that later inputs must not contradict.\nfunc mergeAll(docs []*document) (*document, error) {\n\tfirst := docs[0]\n\tout := &document{\n\t\tname:         \"merged\",\n\t\tOpenAPI:      first.OpenAPI,\n\t\tInfo:         first.Info,\n\t\tServers:      first.Servers,\n\t\tPaths:        newOrderedObject(),\n\t\tWebhooks:     newOrderedObject(),","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/grpc-ecosystem/grpc-gateway/blob/a58a4436a376a4bcc7d8f10c4d4f919a8438bba9/openapiv3-merge/internal/merge/merge.go#L230-L266","documentation":"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.","triggerScenarios":"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 {}.","commonSituations":"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.","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"],"exampleFix":"// before\n{ \"info\": { \"title\": \"api\" }, \"paths\": {} }\n// after\n{ \"openapi\": \"3.1.0\", \"info\": { \"title\": \"api\" }, \"paths\": {} }","handlingStrategy":"validation","validationCode":"func hasOpenAPIField(data []byte) error {\n\tvar doc struct { OpenAPI string `json:\"openapi\"` }\n\tif err := json.Unmarshal(data, &doc); err != nil { return err }\n\tif doc.OpenAPI == \"\" { return errors.New(\"missing required field \\\"openapi\\\"\") }\n\tif !strings.HasPrefix(doc.OpenAPI, \"3.\") { return fmt.Errorf(\"unsupported version %q\", doc.OpenAPI) }\n\treturn nil\n}","typeGuard":"func isOpenAPI3(data []byte) bool {\n\tvar doc struct { OpenAPI string `json:\"openapi\"` }\n\treturn json.Unmarshal(data, &doc) == nil && strings.HasPrefix(doc.OpenAPI, \"3.1\")\n}","tryCatchPattern":"if err := hasOpenAPIField(in.Data); err != nil {\n\treturn fmt.Errorf(\"input %s rejected: %w\", in.Name, err)\n}\nmerged, err := merge.Merge(inputs)","preventionTips":["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"],"tags":["openapi","validation","missing-field"],"backgroundTag":"missing-required-argument","analyzedSha":"a58a4436a376a4bcc7d8f10c4d4f919a8438bba9","analyzedAt":"2026-09-02T10:28:31.537Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}