odysseus-dev/odysseus · error · Error
Email reminder was not sent
Error message
Email reminder was not sent
What it means
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.
Source
Thrown at static/js/settings.js:2707
note_id: 'test-' + Date.now(),
title: 'Test Reminder',
body: 'This is a test reminder to verify your settings are working.',
channel: channelSel.value,
// Mirror the in-UI AI Synthesis toggle + persona so the test never
// races a pending save and lets the user preview changes before
// hitting Save.
llm_synthesis: !!(llmToggle && llmToggle.checked),
llm_persona: (personaSel && personaSel.value) || '',
...(channelSel.value === 'webhook' ? {
webhook_integration_id: webhookIntgSel?.value || '',
webhook_payload_template: webhookTemplateIn?.value.trim() || '',
} : {}),
}),
});
const data = await res.json();
if (!res.ok) throw new Error(data.detail || 'Server error');
if (channelSel.value === 'email' && !data.email_sent) {
throw new Error(data.email_error || 'Email reminder was not sent');
}
if (channelSel.value === 'ntfy' && !data.ntfy_sent) {
throw new Error(data.ntfy_error || 'ntfy reminder was not sent');
}
if (channelSel.value === 'webhook' && !data.webhook_sent) {
const activeChannel = data.channel ? ` (server used channel: "${data.channel}")` : '';
throw new Error((data.webhook_error || 'Webhook reminder was not sent') + activeChannel);
}
let status = 'Delivered via ' + channelSel.value;
if (data.synthesis) status += ' (AI: "' + data.synthesis.slice(0, 60) + '...")';
if (data.email_sent) status += ' — email sent';
if (data.ntfy_sent) status += ' — ntfy sent';
if (data.webhook_sent) status += ' — webhook sent';
if (testMsg) { testMsg.textContent = status; testMsg.style.color = 'var(--green, #50fa7b)'; }
// Also fire a browser notification so user can see it
if ('Notification' in window && Notification.permission === 'granted') {
try {
new Notification('Test Reminder', {View on GitHub (pinned to f9235ebbf1)
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'
Example fix
// before
if (channelSel.value === 'email' && !data.email_sent) {
throw new Error(data.email_error || 'Email reminder was not sent');
}
// after
if (channelSel.value === 'email' && !data.email_sent) {
throw new Error(data.email_error || 'Email reminder was not sent (check SMTP config)');
} Defensive patterns
Strategy: try-catch
Validate before calling
// client can only pre-check channel selection; SMTP health is server-side if (channelSel.value !== 'email') return;
Try / catch
if (channelSel.value === 'email' && !data.email_sent) { throw new Error(data.email_error || 'Email reminder was not sent (check SMTP config)'); } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ntfy reminder was not sent
- Webhook reminder was not sent${activeChannel}
- Unsubscribe failed
- Server error
- Email account {cfg.get('account_name') or account} has no SM
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/ed442d750d57a85f.
Report an issue: GitHub.