{"record":{"id":"975b3a5ffd5b80c3","repo":"grpc-ecosystem/grpc-gateway","slug":"s-openapi-w","errorCode":null,"errorMessage":"%s: openapi: %w","messagePattern":"(.+?): openapi: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"openapiv3-merge/internal/merge/merge.go","lineNumber":206,"sourceCode":"\t\treturn nil, fmt.Errorf(\"%s: expected JSON object at top level\", in.Name)\n\t}\n\tfor dec.More() {\n\t\ttok, err := dec.Token()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%s: %w\", in.Name, err)\n\t\t}\n\t\tkey, ok := tok.(string)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"%s: unexpected token %v\", in.Name, tok)\n\t\t}\n\t\tvar raw json.RawMessage\n\t\tif err := dec.Decode(&raw); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%s: %q: %w\", in.Name, key, err)\n\t\t}\n\t\tswitch key {\n\t\tcase \"openapi\":\n\t\t\tif err := json.Unmarshal(raw, &d.OpenAPI); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"%s: openapi: %w\", in.Name, err)\n\t\t\t}\n\t\tcase \"info\":\n\t\t\td.Info = raw\n\t\tcase \"servers\":\n\t\t\td.Servers = raw\n\t\tcase \"paths\":\n\t\t\tobj, err := decodeOrderedObject(raw)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"%s: paths: %w\", in.Name, err)\n\t\t\t}\n\t\t\td.Paths = obj\n\t\tcase \"webhooks\":\n\t\t\tobj, err := decodeOrderedObject(raw)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"%s: webhooks: %w\", in.Name, err)\n\t\t\t}\n\t\t\td.Webhooks = obj\n\t\tcase \"components\":","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/grpc-ecosystem/grpc-gateway/blob/a58a4436a376a4bcc7d8f10c4d4f919a8438bba9/openapiv3-merge/internal/merge/merge.go#L188-L224","documentation":"This error is returned by the library's internal parse step when the top-level `openapi` field of an input document fails to json.Unmarshal into a string. The `openapi` field of an OpenAPI document must be a JSON string (e.g. \"3.1.0\"), so any other JSON type — number, object, array, bool, or null — causes Unmarshal to fail and the error is wrapped as `<name>: openapi: <cause>`. It is raised while merging inputs via Merge, before any merge logic runs.","triggerScenarios":"Calling Merge with an Input whose Data contains `\"openapi\": 3.0` (number instead of string), `\"openapi\": {\"version\": \"3.0.0\"}`, `\"openapi\": null`, or `\"openapi\": [\"3.0.0\"]` — any non-string JSON value for the `openapi` key.","commonSituations":"Hand-written or template-generated specs where the version was written unquoted (YAML `openapi: 3.0.0` converted carelessly to JSON); code that builds specs programmatically and assigns the version as a float; specs produced by tools that emit an object like `{\"openapi\": {\"value\": \"3.0.3\"}}`.","solutions":["Edit the input document so `openapi` is a quoted JSON string, e.g. \"openapi\": \"3.1.0\".","If the spec is YAML, ensure the conversion to JSON quotes the version (YAML parsers often turn 3.0.0 into a string, but 3.0 into a float).","Validate the input JSON before calling Merge: json.Unmarshal the `openapi` value into a string in your own pre-check to get a clearer error.","If generating specs in code, emit the version as a string literal, never a number or object."],"exampleFix":"// before\n{\"openapi\": 3.1, \"info\": {\"title\": \"api\"}}\n// after\n{\"openapi\": \"3.1.0\", \"info\": {\"title\": \"api\"}}","handlingStrategy":"validation","validationCode":"func validateOpenAPIField(data []byte) error {\n\tvar doc struct {\n\t\tOpenAPI json.RawMessage `json:\"openapi\"`\n\t}\n\tif err := json.Unmarshal(data, &doc); err != nil {\n\t\treturn err\n\t}\n\tvar v string\n\tif err := json.Unmarshal(doc.OpenAPI, &v); err != nil {\n\t\treturn fmt.Errorf(\"openapi must be a JSON string: %w\", err)\n\t}\n\treturn nil\n}","typeGuard":"func isOpenAPIString(raw json.RawMessage) bool {\n\tvar v string\n\treturn json.Unmarshal(raw, &v) == nil\n}","tryCatchPattern":"doc, err := merger.Merge(inputs)\nif err != nil {\n\tvar perr *parseError // or inspect the wrapped message\n\tif strings.Contains(err.Error(), \": openapi: \") {\n\t\treturn fmt.Errorf(\"input spec has invalid openapi version field: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Always quote the OpenAPI version in JSON/YAML output (openapi: \"3.0.3\").","When converting YAML to JSON, force the openapi value to a string to avoid numeric coercion.","Run your specs through a JSON Schema / OpenAPI validator before merging.","Add a CI lint step that json.Unmarshals `openapi` into a string for every spec fed to the merger."],"tags":["json","openapi","type-mismatch","parsing"],"backgroundTag":"json-unmarshal-type-error","analyzedSha":"a58a4436a376a4bcc7d8f10c4d4f919a8438bba9","analyzedAt":"2026-09-02T10:28:31.537Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}