{"record":{"id":"a8cd17c801f290b5","repo":"kopia/kopia","slug":"error-preparing-pushover-notification","errorCode":null,"errorMessage":"error preparing pushover notification","messagePattern":"error preparing pushover notification","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"notification/sender/pushover/pushover_sender.go","lineNumber":44,"sourceCode":"func (p *pushoverProvider) Send(ctx context.Context, msg *sender.Message) error {\n\tpayload := map[string]string{\n\t\t\"token\":   p.opt.AppToken,\n\t\t\"user\":    p.opt.UserKey,\n\t\t\"message\": msg.Subject + \"\\n\\n\" + msg.Body,\n\t}\n\n\tif p.Format() == \"html\" {\n\t\tpayload[\"html\"] = \"1\"\n\t}\n\n\ttargetURL := defaultPushoverURL\n\tif p.opt.Endpoint != \"\" {\n\t\ttargetURL = p.opt.Endpoint\n\t}\n\n\tbody, err := json.Marshal(payload)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"error preparing pushover notification\")\n\t}\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, targetURL, bytes.NewReader(body))\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"error preparing pushover notification\")\n\t}\n\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"error sending pushover notification\")\n\t}\n\n\tdefer resp.Body.Close() //nolint:errcheck\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn errors.Errorf(\"error sending pushover notification: %v\", resp.Status)","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/kopia/kopia/blob/82495e54b584c1ef6073c9e1be048f57f8aef078/notification/sender/pushover/pushover_sender.go#L26-L62","documentation":"The pushover sender's Send serializes its payload with json.Marshal and then builds the HTTP request; both failures are wrapped as 'error preparing pushover notification' (this instance is the marshaling step). It means the payload could not be converted to JSON before the request is sent.","triggerScenarios":"Calling Send on a pushover provider whose payload contains a value json.Marshal cannot serialize (unsupported type, invalid float like NaN/Inf, or a MarshalJSON returning an error).","commonSituations":"Placing non-serializable values (channels, funcs, NaN) into the message/title/URL fields; custom option types added to the payload struct; corrupted Endpoint option does NOT cause this error (it only affects the request build).","solutions":["Inspect the wrapped error via errors.Unwrap to identify the offending field.","Ensure all payload fields (message, title, etc.) are plain JSON-serializable types.","Fix or remove custom MarshalJSON implementations used in payload values.","Sanitize numeric fields to avoid NaN/Inf values before calling Send."],"exampleFix":"// before\npayload[\"priority\"] = computedPriority // may be NaN\n// after\nif math.IsNaN(computedPriority) { computedPriority = 0 }\npayload[\"priority\"] = computedPriority","handlingStrategy":"validation","validationCode":"func preflightPushoverPayload(payload map[string]any) error {\n  _, err := json.Marshal(payload)\n  return err\n}","typeGuard":null,"tryCatchPattern":"if err := p.Send(ctx, msg); err != nil {\n  if strings.Contains(err.Error(), \"error preparing pushover notification\") {\n    return fmt.Errorf(\"pushover payload failed to build (check serializable fields and endpoint URL): %w\", err)\n  }\n  return err\n}","preventionTips":["Keep payload fields JSON-primitive; avoid NaN/Inf.","Validate the endpoint with url.Parse at construction time.","Preflight json.Marshal in tests for your payload shape."],"tags":["pushover","json","serialization"],"backgroundTag":"json-marshal-failed","analyzedSha":"82495e54b584c1ef6073c9e1be048f57f8aef078","analyzedAt":"2026-09-07T20:35:21.689Z","contentChangedAt":"2026-09-07T20:35:21.689Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}