{"record":{"id":"6f17b8aa51445893","repo":"grpc-ecosystem/grpc-gateway","slug":"failed-to-parse-openapi-configuration-from-yaml-in","errorCode":null,"errorMessage":"failed to parse OpenAPI Configuration from YAML in %q: %w","messagePattern":"failed to parse OpenAPI Configuration from YAML in %q: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/descriptor/openapi_configuration.go","lineNumber":31,"sourceCode":"func loadOpenAPIConfigFromYAML(yamlFileContents []byte, yamlSourceLogName string) (*openapiconfig.OpenAPIConfig, error) {\n\tvar yamlContents interface{}\n\tif err := yaml.Unmarshal(yamlFileContents, &yamlContents); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse gRPC API Configuration from YAML in %q: %w\", yamlSourceLogName, err)\n\t}\n\n\tjsonContents, err := json.Marshal(yamlContents)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Reject unknown fields because OpenAPIConfig is only used here\n\tunmarshaler := protojson.UnmarshalOptions{\n\t\tDiscardUnknown: false,\n\t}\n\n\topenapiConfiguration := openapiconfig.OpenAPIConfig{}\n\tif err := unmarshaler.Unmarshal(jsonContents, &openapiConfiguration); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse OpenAPI Configuration from YAML in %q: %w\", yamlSourceLogName, err)\n\t}\n\n\treturn &openapiConfiguration, nil\n}\n\nfunc registerOpenAPIOptions(registry *Registry, openAPIConfig *openapiconfig.OpenAPIConfig, yamlSourceLogName string) error {\n\tif openAPIConfig.OpenapiOptions == nil {\n\t\t// Nothing to do\n\t\treturn nil\n\t}\n\n\tif err := registry.RegisterOpenAPIOptions(openAPIConfig.OpenapiOptions); err != nil {\n\t\treturn fmt.Errorf(\"failed to register option in %s: %w\", yamlSourceLogName, err)\n\t}\n\treturn nil\n}\n\n// LoadOpenAPIConfigFromYAML loads an  OpenAPI Configuration from the given YAML file","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/grpc-ecosystem/grpc-gateway/blob/a58a4436a376a4bcc7d8f10c4d4f919a8438bba9/internal/descriptor/openapi_configuration.go#L13-L49","documentation":"loadOpenAPIConfigFromYAML fails when the YAML is syntactically valid but does not conform to the OpenAPIConfig proto message: protojson.Unmarshal with DiscardUnknown:false rejects unknown fields, wrong types, or misspelled keys. The YAML is first converted to JSON, then decoded into openapiconfig.OpenAPIConfig.","triggerScenarios":"LoadOpenAPIConfigFromYAML given a config containing keys not present in OpenAPIConfig (e.g. typos like 'openapi_options' instead of 'openapiOptions'-equivalent snake_case names, or unexpected nested fields).","commonSituations":"Upgrading protoc-gen-openapiv2 to a version that removed/renamed a config field; following outdated documentation; typo in a field name; wrong casing of snake_case field names.","solutions":["Remove or rename unknown fields to match openapiv2.OpenAPIConfig field names (snake_case of the proto fields)","Check the OpenAPIConfig proto definition for your version and update config accordingly","Temporarily diff the config against a working example from the same library version","Pin the generator and config to compatible versions when upgrading"],"exampleFix":"// before\nopenapiOptions:\n  openapi_operation_optionz:\n    - selector: \"my.service.Foo\"\n// after\nopenapiOptions:\n  openapiOperationOptions:\n    - selector: \"my.service.Foo\"","handlingStrategy":"validation","validationCode":"var raw map[string]interface{}\nif err := yaml.Unmarshal(contents, &raw); err != nil { return err }\nallowed := map[string]bool{\"type\": true, \"openapiOptions\": true, /* fields of OpenAPIConfig */}\nfor k := range raw {\n    if !allowed[k] {\n        return fmt.Errorf(\"unknown config key %q\", k)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := reg.LoadOpenAPIConfigFromYAML(path); err != nil {\n    var uerr *protojson.UnmarshalError\n    if errors.As(err, &uerr) || strings.Contains(err.Error(), \"unknown field\") {\n        log.Fatalf(\"config field mismatch in %s: %v\", path, err)\n    }\n    return err\n}","preventionTips":["Pin protoc-gen-openapiv2 version and keep config compatible with it","Check the OpenAPIConfig proto for your version when adding fields","Test config loading in CI with the same generator version","Diff against example configs from the repo"],"tags":["schema-validation","protojson","config"],"backgroundTag":"schema-validation-failed","analyzedSha":"a58a4436a376a4bcc7d8f10c4d4f919a8438bba9","analyzedAt":"2026-09-02T10:28:31.537Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}