{"record":{"id":"35a8588f81c7cc43","repo":"grpc-ecosystem/grpc-gateway","slug":"failed-to-encode-openapi-for-s-w","errorCode":null,"errorMessage":"failed to encode OpenAPI for %s: %w","messagePattern":"failed to encode OpenAPI for (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"protoc-gen-openapiv2/internal/genopenapi/generator.go","lineNumber":451,"sourceCode":"\t\t\tcontinue\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\topenapis = append(openapis, &wrapper{\n\t\t\tfileName: file.GetName(),\n\t\t\tswagger:  swagger,\n\t\t})\n\t}\n\n\tif g.reg.IsAllowMerge() {\n\t\ttargetOpenAPI := mergeTargetFile(openapis, g.reg.GetMergeFileName())\n\t\tif !g.reg.IsPreserveRPCOrder() {\n\t\t\ttargetOpenAPI.swagger.sortPathsAlphabetically()\n\t\t}\n\t\tf, err := encodeOpenAPI(targetOpenAPI, g.format)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to encode OpenAPI for %s: %w\", g.reg.GetMergeFileName(), err)\n\t\t}\n\t\tfiles = append(files, f)\n\t\tif grpclog.V(1) {\n\t\t\tgrpclog.Infof(\"New OpenAPI file will emit\")\n\t\t}\n\t} else {\n\t\tfor _, file := range openapis {\n\t\t\tif !g.reg.IsPreserveRPCOrder() {\n\t\t\t\tfile.swagger.sortPathsAlphabetically()\n\t\t\t}\n\t\t\tf, err := encodeOpenAPI(file, g.format)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to encode OpenAPI for %s: %w\", file.fileName, err)\n\t\t\t}\n\t\t\tfiles = append(files, f)\n\t\t\tif grpclog.V(1) {\n\t\t\t\tgrpclog.Infof(\"New OpenAPI file will emit\")\n\t\t\t}","sourceCodeStart":433,"sourceCodeEnd":469,"githubUrl":"https://github.com/grpc-ecosystem/grpc-gateway/blob/a58a4436a376a4bcc7d8f10c4d4f919a8438bba9/protoc-gen-openapiv2/internal/genopenapi/generator.go#L433-L469","documentation":"In genopenapi's Generator.Generate, when the OpenAPI registry is in merged-output mode, all per-file OpenAPI docs are merged and encoded into a single file named by reg.GetMergeFileName(). If encodeOpenAPI fails (JSON/YAML marshaling of the merged swagger document), the error is wrapped as 'failed to encode OpenAPI for %s: %w'. The inner error identifies why the document could not be serialized.","triggerScenarios":"Generate() with merge mode enabled (single output file configured) where encodeOpenAPI(targetOpenAPI, g.format) returns an error — typically json.MarshalIndent failures from invalid/unsupported values (e.g. NaN, malformed extension values) or YAML encoding problems in the merged document.","commonSituations":"Custom OpenAPI options or extensions inject values that don't serialize (invalid custom openapiv2 options); a broken plugin hook adds malformed fields; extremely deep nesting hitting marshal recursion issues.","solutions":["Read the wrapped inner error to find the exact field/value that failed to marshal.","Audit openapiv2 options in your protos for invalid extension values or unsupported types in custom fields.","Try switching g.format (json vs yaml) to isolate whether the YAML or JSON encoder is at fault.","Bisect by generating per-file output (disable merge) to find which input proto produces the bad content."],"exampleFix":"// before: openapiv2_option with bad custom extension causing marshal failure\noption (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { extensions: { key: \"x-bad\" value { struct_value { } } } };\n// after: remove or fix the extension so it serializes\noption (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { info: { title: \"API\" version: \"1.0\" } };","handlingStrategy":"try-catch","validationCode":"// Validate generated OpenAPI options serialize cleanly before generation:\n_, err := json.Marshal(mergedSwaggerDoc)\nif err != nil { log.Fatalf(\"openapi document not serializable: %v\", err) }","typeGuard":null,"tryCatchPattern":"if err := runProtocGenOpenAPIv2(); err != nil {\n    var encErr *EncodingError\n    if errors.As(err, &encErr) {\n        log.Fatalf(\"failed to encode OpenAPI for %s: %v\", encErr.File, errors.Unwrap(err))\n    }\n    return err\n}","preventionTips":["Keep openapiv2 options to documented field types only.","Avoid ad-hoc extensions with exotic protobuf Value types.","Test OpenAPI generation in CI so marshal breakages surface immediately."],"tags":["codegen","openapi","serialization","merge-mode"],"backgroundTag":"openapi-encode-failed","analyzedSha":"a58a4436a376a4bcc7d8f10c4d4f919a8438bba9","analyzedAt":"2026-09-02T10:28:31.537Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}