{"record":{"id":"50bb2d04b57e3a48","repo":"knadh/listmonk","slug":"missing-event-data","errorCode":null,"errorMessage":"missing event data","messagePattern":"missing event data","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/bounce/webhooks/azure.go","lineNumber":72,"sourceCode":"// returns the response payload that should be written to HTTP response body.\nfunc (a *Azure) ProcessSubscription(b []byte) (json.RawMessage, error) {\n\tevents, err := parseAzureEvents(b)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(events) == 0 {\n\t\treturn nil, errors.New(\"empty event payload\")\n\t}\n\n\t// Validation code arrives in the first event for subscription validation flow.\n\tvar payload map[string]json.RawMessage\n\tif err := json.Unmarshal(events[0].RawData, &payload); err != nil {\n\t\treturn nil, fmt.Errorf(\"error reading validation payload: %v\", err)\n\t}\n\n\trawData, ok := payload[\"data\"]\n\tif !ok {\n\t\treturn nil, errors.New(\"missing event data\")\n\t}\n\n\tvar data map[string]string\n\tif err := json.Unmarshal(rawData, &data); err != nil {\n\t\treturn nil, fmt.Errorf(\"error reading validation data: %v\", err)\n\t}\n\n\tcode := strings.TrimSpace(data[\"validationCode\"])\n\tif code == \"\" {\n\t\treturn nil, errors.New(\"missing validationCode in subscription payload\")\n\t}\n\n\tres, _ := json.Marshal(map[string]string{\n\t\t\"validationResponse\": code,\n\t})\n\treturn json.RawMessage(res), nil\n}\n","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/knadh/listmonk/blob/670c01717d48647093335cc23a6be6f4b79c3b6b/internal/bounce/webhooks/azure.go#L54-L90","documentation":"ProcessSubscription unmarshals the first event's RawData and expects a \"data\" key holding the validation payload. This error is returned when that key is absent from the event data. The library throws it to prevent a nil/missing-data dereference when extracting the validationCode.","triggerScenarios":"The first Azure Event Grid event's Data field does not contain a \"data\" key — e.g. the event is not a subscription validation event (handshake/data events have different shapes) or the event payload was transformed/stripped in transit.","commonSituations":"Sending a regular bounce notification event to the subscription-validation code path; an intermediary (API gateway, Event Grid filter/schema like CloudEvents envelope) that renames or nests the data field; testing with handcrafted payloads missing \"data\".","solutions":["Ensure the payload sent during subscription registration is an actual SubscriptionValidationEvent whose Data contains validationCode under the expected key.","Inspect events[0].RawData (log it) to see the actual shape and adjust payload construction accordingly.","If using the CloudEvents schema in Event Grid, adjust the webhook or parser to expect the enveloped format.","Add a pre-check that the first event's data exists before calling ProcessSubscription."],"exampleFix":"// before\nvar payload map[string]json.RawMessage\njson.Unmarshal(events[0].RawData, &payload)\nres, err := azure.ProcessSubscription(body)\n// after\nvar probe map[string]json.RawMessage\nif json.Unmarshal(events[0].RawData, &probe) == nil {\n\tif _, ok := probe[\"data\"]; !ok {\n\t\t// not a subscription validation event; route elsewhere\n\t}\n}","handlingStrategy":"type-guard","validationCode":"var probe map[string]json.RawMessage\nif err := json.Unmarshal(firstEventRawData, &probe); err != nil || probe[\"data\"] == nil {\n\t// not a subscription validation payload; route to ProcessBounce instead\n}","typeGuard":"func isValidationEvent(raw json.RawMessage) bool {\n\tvar p map[string]json.RawMessage\n\tif json.Unmarshal(raw, &p) != nil { return false }\n\t_, ok := p[\"data\"]\n\treturn ok\n}","tryCatchPattern":"res, err := azure.ProcessSubscription(body)\nif err != nil {\n\tif strings.Contains(err.Error(), \"missing event data\") {\n\t\t// payload is likely a bounce delivery, not validation: forward to ProcessBounce\n\t\treturn azure.ProcessBounce(body, req)\n\t}\n\treturn err\n}","preventionTips":["Route validation vs delivery events by eventType before calling ProcessSubscription.","Beware CloudEvents/CE envelope schema: keys differ; configure Event Grid delivery schema consistently.","Log RawData when this error occurs to see the real shape.","Never handcraft validation payloads without a \"data\" object."],"tags":["azure","event-grid","webhook","payload-shape"],"backgroundTag":"missing-webhook-event-data","analyzedSha":"670c01717d48647093335cc23a6be6f4b79c3b6b","analyzedAt":"2026-09-01T03:39:35.452Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}