{"record":{"id":"bb1a247537686d86","repo":"grpc-ecosystem/grpc-gateway","slug":"s-webhooks-w","errorCode":null,"errorMessage":"%s: webhooks: %w","messagePattern":"(.+?): webhooks: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"openapiv3-merge/internal/merge/merge.go","lineNumber":221,"sourceCode":"\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\":\n\t\t\tif !isJSONNull(raw) {\n\t\t\t\tif err := json.Unmarshal(raw, d.Components); err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"%s: components: %w\", in.Name, err)\n\t\t\t\t}\n\t\t\t}\n\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","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/grpc-ecosystem/grpc-gateway/blob/a58a4436a376a4bcc7d8f10c4d4f919a8438bba9/openapiv3-merge/internal/merge/merge.go#L203-L239","documentation":"This error is returned when the top-level `webhooks` field of an input document is not a JSON object. parse calls decodeOrderedObject on the raw value to preserve webhook insertion order; the value must be an object mapping webhook names to path items, so arrays, strings, null, or other non-object types fail and are wrapped as `<name>: webhooks: <cause>`.","triggerScenarios":"Calling Merge with an Input whose Data contains `\"webhooks\": []` (array), `\"webhooks\": \"...\"`, `\"webhooks\": null`, or any other non-object JSON value under `webhooks`.","commonSituations":"Specs generated from structs where Webhooks was a nil slice serialized as null/[]; templates that scaffold webhooks as a list; tools that emit webhooks as an array of objects; hand-edited specs where the map braces were lost.","solutions":["Edit the input so `webhooks` is a JSON object, e.g. \"webhooks\": {\"newPet\": {...}} (use {} or omit the key if there are none).","If serializing from code, initialize Webhooks as a map so it marshals as {} instead of null or [].","Fix the upstream generator/tool to emit webhooks as a keyed object, matching the OpenAPI 3.1 spec shape.","Pre-validate by decoding `webhooks` into map[string]json.RawMessage before calling Merge."],"exampleFix":"// before\n{\"openapi\": \"3.1.0\", \"webhooks\": [\"newPet\"]}\n// after\n{\"openapi\": \"3.1.0\", \"webhooks\": {\"newPet\": {\"post\": {\"responses\": {\"200\": {\"description\": \"ok\"}}}}}}","handlingStrategy":"validation","validationCode":"func validateWebhooksField(data []byte) error {\n\tvar doc struct {\n\t\tWebhooks json.RawMessage `json:\"webhooks\"`\n\t}\n\tif err := json.Unmarshal(data, &doc); err != nil {\n\t\treturn err\n\t}\n\tif len(doc.Webhooks) == 0 || string(doc.Webhooks) == \"null\" {\n\t\treturn nil\n\t}\n\tvar m map[string]json.RawMessage\n\tif err := json.Unmarshal(doc.Webhooks, &m); err != nil {\n\t\treturn fmt.Errorf(\"webhooks must be a JSON object: %w\", err)\n\t}\n\treturn nil\n}","typeGuard":"func isWebhooksObject(raw json.RawMessage) bool {\n\tvar m map[string]json.RawMessage\n\treturn len(raw) > 0 && json.Unmarshal(raw, &m) == nil\n}","tryCatchPattern":"merged, err := merger.Merge(inputs)\nif err != nil {\n\tif strings.Contains(err.Error(), \": webhooks: \") {\n\t\treturn fmt.Errorf(\"input spec has a non-object webhooks field: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Emit webhooks as a keyed object per OpenAPI 3.1 (webhooks: {name: pathItem}), never an array.","Initialize webhook containers as maps when generating specs so they marshal to {} not null.","Validate specs against the OpenAPI 3.1 schema before merging.","If the source tool emits webhooks as a list, transform it to a keyed object in your ingestion pipeline."],"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"}