{"record":{"id":"f3835063a8ea7291","repo":"koala73/worldmonitor","slug":"createprolaunchbroadcast-resend-res-status","errorCode":null,"errorMessage":"[createProLaunchBroadcast] Resend ${res.status}: ${body}","messagePattern":"\\[createProLaunchBroadcast\\] Resend (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"convex/broadcast/sendBroadcast.ts","lineNumber":112,"sourceCode":"      headers: {\n        \"Content-Type\": \"application/json\",\n        Authorization: `Bearer ${apiKey}`,\n        \"User-Agent\": USER_AGENT,\n      },\n      body: JSON.stringify({\n        name,\n        segment_id: segmentId,\n        from: PRO_LAUNCH_FROM,\n        reply_to: PRO_LAUNCH_REPLY_TO,\n        subject: PRO_LAUNCH_SUBJECT,\n        html: PRO_LAUNCH_HTML,\n        text: PRO_LAUNCH_TEXT,\n      }),\n    });\n\n    if (!res.ok) {\n      const body = await res.text().catch(() => \"<no body>\");\n      throw new Error(\n        `[createProLaunchBroadcast] Resend ${res.status}: ${body}`,\n      );\n    }\n\n    const json = (await res.json().catch(() => null)) as {\n      id?: string;\n    } | null;\n    if (!json?.id) {\n      throw new Error(\n        `[createProLaunchBroadcast] Resend response missing id: ${JSON.stringify(json)}`,\n      );\n    }\n\n    return {\n      broadcastId: json.id,\n      name,\n      segmentId,\n      subject: PRO_LAUNCH_SUBJECT,","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/koala73/worldmonitor/blob/ffec79ac339946fd2d24e85845da5755dcaa534b/convex/broadcast/sendBroadcast.ts#L94-L130","documentation":"Thrown when the Resend POST /broadcasts endpoint returns a non-2xx status during createProLaunchBroadcast. The error includes the HTTP status code and the raw response body (or '<no body>' if the body read itself failed). This is a passthrough of the upstream Resend API error — the message format is `[createProLaunchBroadcast] Resend <status>: <body>`.","triggerScenarios":"Calling createProLaunchBroadcast with an invalid or deleted segmentId (Resend 404/422). Using an expired or revoked RESEND_API_KEY (401/403). Hitting Resend rate limits (429). Resend service outage or 5xx. The 'from' address PRO_LAUNCH_FROM not verified in the Resend account (422).","commonSituations":"The segmentId was copied from the wrong Resend workspace. The API key was rotated in the Resend dashboard but the Convex env var was not updated. The 'from' domain news@worldmonitor.app lost its DNS verification. A transient Resend outage coincides with the send window.","solutions":["Read the embedded status code and body: 401/403 means the RESEND_API_KEY Convex env var is wrong/expired — rotate it in the Resend dashboard and update the Convex variable. 422 usually means the segmentId or from-address is invalid — verify both in the Resend dashboard. 429 means back off and retry.","Verify the segmentId exists in the same Resend workspace the API key belongs to.","Confirm PRO_LAUNCH_FROM ('Elie from WorldMonitor <news@worldmonitor.app>') is a verified sender identity in Resend.","For 5xx or 429, retry createProLaunchBroadcast after a short backoff — the action is not idempotent, so check the Resend dashboard first to avoid creating a duplicate broadcast."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const result = await ctx.runAction(internal.broadcast.sendBroadcast.createProLaunchBroadcast, { segmentId });\n  // store result.broadcastId\n} catch (err) {\n  const msg = String(err);\n  if (msg.includes(\"Resend 429\") || msg.includes(\"Resend 5\")) {\n    // transient — back off and retry, but check Resend dashboard for duplicates first\n    await sleep(backoffMs);\n    throw err; // re-throw for scheduler retry\n  }\n  if (msg.includes(\"Resend 401\") || msg.includes(\"Resend 403\")) {\n    // API key issue — do not retry; surface to operator\n    throw err;\n  }\n  // 422/404 — segmentId or from-address invalid; do not retry blindly\n  throw err;\n}","preventionTips":["Verify the segmentId exists in the Resend dashboard before calling createProLaunchBroadcast.","Confirm PRO_LAUNCH_FROM is a verified sender identity in Resend.","Keep RESEND_API_KEY current — rotate in both Resend and Convex env simultaneously.","Create broadcasts well ahead of the send window so transient Resend errors have time to clear."],"tags":["resend","email-broadcast","network","api-error","convex"],"backgroundTag":null,"analyzedSha":"ffec79ac339946fd2d24e85845da5755dcaa534b","analyzedAt":"2026-08-12T11:24:56.012Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}