{"record":{"id":"ed442d750d57a85f","repo":"odysseus-dev/odysseus","slug":"email-reminder-was-not-sent","errorCode":null,"errorMessage":"Email reminder was not sent","messagePattern":"Email reminder was not sent","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"static/js/settings.js","lineNumber":2707,"sourceCode":"            note_id: 'test-' + Date.now(),\n            title: 'Test Reminder',\n            body: 'This is a test reminder to verify your settings are working.',\n            channel: channelSel.value,\n            // Mirror the in-UI AI Synthesis toggle + persona so the test never\n            // races a pending save and lets the user preview changes before\n            // hitting Save.\n            llm_synthesis: !!(llmToggle && llmToggle.checked),\n            llm_persona: (personaSel && personaSel.value) || '',\n            ...(channelSel.value === 'webhook' ? {\n              webhook_integration_id: webhookIntgSel?.value || '',\n              webhook_payload_template: webhookTemplateIn?.value.trim() || '',\n            } : {}),\n          }),\n        });\n        const data = await res.json();\n        if (!res.ok) throw new Error(data.detail || 'Server error');\n        if (channelSel.value === 'email' && !data.email_sent) {\n          throw new Error(data.email_error || 'Email reminder was not sent');\n        }\n        if (channelSel.value === 'ntfy' && !data.ntfy_sent) {\n          throw new Error(data.ntfy_error || 'ntfy reminder was not sent');\n        }\n        if (channelSel.value === 'webhook' && !data.webhook_sent) {\n          const activeChannel = data.channel ? ` (server used channel: \"${data.channel}\")` : '';\n          throw new Error((data.webhook_error || 'Webhook reminder was not sent') + activeChannel);\n        }\n        let status = 'Delivered via ' + channelSel.value;\n        if (data.synthesis) status += ' (AI: \"' + data.synthesis.slice(0, 60) + '...\")';\n        if (data.email_sent) status += ' — email sent';\n        if (data.ntfy_sent) status += ' — ntfy sent';\n        if (data.webhook_sent) status += ' — webhook sent';\n        if (testMsg) { testMsg.textContent = status; testMsg.style.color = 'var(--green, #50fa7b)'; }\n        // Also fire a browser notification so user can see it\n        if ('Notification' in window && Notification.permission === 'granted') {\n          try {\n            new Notification('Test Reminder', {","sourceCodeStart":2689,"sourceCodeEnd":2725,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/static/js/settings.js#L2689-L2725","documentation":"Delivery-level failure for email test reminders. The POST succeeded (res.ok), but the response body has email_sent falsy while the channel selector is 'email'. The thrown message is data.email_error when the server provides it, otherwise this literal string.","triggerScenarios":"Channel 'email' selected and POST /api/.../test returns 200 with {email_sent: false} — SMTP host unreachable, bad credentials, missing from-address, or a server-side send exception captured into email_error.","commonSituations":"SMTP not configured or credentials rotated; firewall blocking outbound SMTP (port 25/587); typo'd mail server; provider rejecting the test message; email_error field absent so the generic text shows.","solutions":["Inspect data.email_error in the response body for the server-captured SMTP error","Verify SMTP settings (host, port, user, password, TLS) on the server","Confirm outbound SMTP is reachable from the server host","Fall back to a fuller message when email_error is missing, e.g. include 'check SMTP config'"],"exampleFix":"// before\n        if (channelSel.value === 'email' && !data.email_sent) {\n          throw new Error(data.email_error || 'Email reminder was not sent');\n        }\n\n// after\n        if (channelSel.value === 'email' && !data.email_sent) {\n          throw new Error(data.email_error || 'Email reminder was not sent (check SMTP config)');\n        }","handlingStrategy":"try-catch","validationCode":"// client can only pre-check channel selection; SMTP health is server-side\nif (channelSel.value !== 'email') return;","typeGuard":null,"tryCatchPattern":"if (channelSel.value === 'email' && !data.email_sent) { throw new Error(data.email_error || 'Email reminder was not sent (check SMTP config)'); }","preventionTips":["Always log data.email_error when present — it carries the SMTP failure","Validate SMTP settings server-side before enabling the email channel","Prefer surfacing email_error over the generic fallback in the UI","Keep a server-side SMTP connectivity self-check endpoint for pre-flight"],"tags":["reminders","email","smtp","delivery","settings"],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}