{"record":{"id":"2c2f887a093162cb","repo":"grpc-ecosystem/grpc-gateway","slug":"s-missing-required-field-info","errorCode":null,"errorMessage":"%s: missing required field \"info\"","messagePattern":"(.+?): missing required field \"info\"","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"openapiv3-merge/internal/merge/merge.go","lineNumber":251,"sourceCode":"\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(),\n\t\tComponents:   &components{},\n\t\tExternalDocs: first.ExternalDocs,\n\t\textras:       newOrderedObject(),","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/grpc-ecosystem/grpc-gateway/blob/a58a4436a376a4bcc7d8f10c4d4f919a8438bba9/openapiv3-merge/internal/merge/merge.go#L233-L269","documentation":"Raised in parse() when a document's top-level object has no \"info\" object (or it is JSON null). The OpenAPI spec requires \"info\", so this library rejects any input missing it. The message names the offending input document.","triggerScenarios":"Calling Merge with an Input whose Data lacks a top-level \"info\" object, or sets \"info\": null explicitly — common in generated fragments or minimal stubs.","commonSituations":"Generator configs that suppress metadata, hand-trimmed documents, migration tools that dropped info, or templated files where the info block was never filled in.","solutions":["Add a top-level \"info\" object with at least \"title\" and \"version\" to the named document","If the value is explicitly null, replace it with a real object","Fix the generator/template so it emits the info block","Check that you are not accidentally passing a stripped sub-document"],"exampleFix":"// before\n{ \"openapi\": \"3.1.0\", \"paths\": {} }\n// after\n{ \"openapi\": \"3.1.0\", \"info\": { \"title\": \"my api\", \"version\": \"1.0.0\" }, \"paths\": {} }","handlingStrategy":"validation","validationCode":"func hasInfoField(data []byte) error {\n\tvar doc map[string]json.RawMessage\n\tif err := json.Unmarshal(data, &doc); err != nil { return err }\n\traw, ok := doc[\"info\"]\n\tif !ok || string(bytes.TrimSpace(raw)) == \"null\" {\n\t\treturn errors.New(\"missing required field \\\"info\\\"\")\n\t}\n\treturn nil\n}","typeGuard":"func hasInfo(data []byte) bool {\n\tvar doc struct { Info json.RawMessage `json:\"info\"` }\n\tif json.Unmarshal(data, &doc) != nil { return false }\n\treturn len(bytes.TrimSpace(doc.Info)) > 0 && !bytes.Equal(bytes.TrimSpace(doc.Info), []byte(\"null\"))\n}","tryCatchPattern":"if err := hasInfoField(in.Data); err != nil {\n\treturn fmt.Errorf(\"input %s: %w\", in.Name, err)\n}\nmerged, err := merge.Merge(inputs)","preventionTips":["Ensure generator configs always emit an info block with title and version","Never set \"info\": null in spec templates","Validate inputs against the OpenAPI 3.1 schema in CI","Keep full documents (not stripped fragments) as merge inputs"],"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"}