{"record":{"id":"08b48efc3d4f82d3","repo":"amir20/dozzle","slug":"webhook-notification-failed-s","errorCode":null,"errorMessage":"webhook notification failed: %s","messagePattern":"webhook notification failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/notification/dispatcher/webhook.go","lineNumber":209,"sourceCode":"\t\t}\n\t\tw.Template = tmpl\n\t}\n\n\treturn w, nil\n}\n\n// TestResult contains the result of a webhook test\ntype TestResult struct {\n\tSuccess    bool\n\tStatusCode int\n\tError      string\n}\n\n// Send sends a notification to the webhook URL\nfunc (w *WebhookDispatcher) Send(ctx context.Context, notification types.Notification) error {\n\tresult := w.SendTest(ctx, notification)\n\tif !result.Success {\n\t\treturn fmt.Errorf(\"webhook notification failed: %s\", result.Error)\n\t}\n\treturn nil\n}\n\n// SendTest sends a notification and returns detailed result for testing\nfunc (w *WebhookDispatcher) SendTest(ctx context.Context, notification types.Notification) TestResult {\n\tvar payload []byte\n\tvar err error\n\n\tif w.Template != nil {\n\t\tpayload, err = executeJSONTemplate(w.TemplateText, notification)\n\t\tif err != nil {\n\t\t\treturn TestResult{Success: false, Error: fmt.Sprintf(\"failed to execute template: %v\", err)}\n\t\t}\n\t} else {\n\t\tpayload, err = json.Marshal(notification)\n\t\tif err != nil {\n\t\t\treturn TestResult{Success: false, Error: fmt.Sprintf(\"failed to marshal notification: %v\", err)}","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/amir20/dozzle/blob/d9463cbe21874e44ab79db6fa63e746ca7d22928/internal/notification/dispatcher/webhook.go#L191-L227","documentation":"WebhookDispatcher.Send delegates to SendTest and converts a failed TestResult into a plain error, discarding the structured result. Any failure inside SendTest (template execution, HTTP request error, non-2xx response, refused private/loopback target, oversized reflection) surfaces here with this message.","triggerScenarios":"Calling WebhookDispatcher.Send when the target URL is unreachable, returns a non-2xx status, the rendered payload fails, or SendTest's SSRF guards reject the target.","commonSituations":"Webhook receiver down or moved; firewall blocking outbound calls from the Dozzle container; receiver returning 500 on the payload; misconfigured headers/auth on the endpoint.","solutions":["Prefer SendTest during setup to get the detailed TestResult (Error field, status, response body)","Unwrap result.Error / the returned message to see the underlying cause (DNS, timeout, status code)","Verify the endpoint is reachable from the Dozzle container and returns 2xx for the payload","Check SSRF guards: loopback and link-local targets are refused by design"],"exampleFix":"// before\nerr := w.Send(ctx, n) // loses detail\n// after\nres := w.SendTest(ctx, n)\nif !res.Success {\n    log.Error().Str(\"detail\", res.Error).Msg(\"webhook failed\")\n}","handlingStrategy":"try-catch","validationCode":"res := w.SendTest(ctx, testNotification)\nif !res.Success {\n    return errors.New(res.Error)\n}","typeGuard":null,"tryCatchPattern":"if err := w.Send(ctx, n); err != nil {\n    // log err; use SendTest in diagnostics for the structured cause\n}","preventionTips":["Use SendTest with a test notification when configuring a webhook","Confirm the endpoint returns 2xx for the rendered payload","Remember Send drops detail; handle SendTest results for observability"],"tags":["webhook","http","network","notifications"],"backgroundTag":"http-request-failed","analyzedSha":"d9463cbe21874e44ab79db6fa63e746ca7d22928","analyzedAt":"2026-09-07T10:08:55.855Z","contentChangedAt":"2026-09-07T10:08:55.855Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}