odysseus-dev/odysseus · error · Error
Webhook reminder was not sent${activeChannel}
Error message
Webhook reminder was not sent${activeChannel} What it means
Delivery-level failure for webhook test reminders; the literal '${activeChannel}' in the source is a template interpolation — the real message appends (server used channel: "X") when the server reports which channel it actually used, exposing channel-mismatch situations. Thrown when channel is 'webhook' and data.webhook_sent is falsy.
Source
Thrown at static/js/settings.js:2714
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', {
body: data.synthesis || 'This is a test reminder.',
tag: 'reminder-test',
icon: '/static/favicon.ico',
});
} catch {}
}
} catch (e) {View on GitHub (pinned to f9235ebbf1)
Solutions
- Inspect data.webhook_error and data.channel in the response body
- Verify the chosen integration id still exists and its URL responds
- Test the target endpoint directly with the rendered payload
- If the appended note shows a different channel, fix why the server overrode 'webhook' (usually missing integration_id)
Example fix
// before
throw new Error((data.webhook_error || 'Webhook reminder was not sent') + activeChannel);
// after
throw new Error((data.webhook_error || 'Webhook reminder was not sent (verify integration URL/template)') + activeChannel); Defensive patterns
Strategy: try-catch
Validate before calling
if (channelSel.value === 'webhook' && channelSel.value === 'webhook' && !webhookIntgSel?.value) {
if (testMsg) { testMsg.textContent = 'Select a webhook integration first'; testMsg.style.color = 'var(--red)'; }
return;
} Try / catch
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); } Prevention
- Require a webhook integration selection before enabling test
- Validate the payload template against the integration's schema
- Log data.webhook_error and data.channel for mismatch diagnosis
- Keep the activeChannel suffix — it exposes server-side channel overrides
When it happens
Trigger: POST test returns 200 with {webhook_sent: false} — webhook integration id missing/deleted, payload template invalid, target URL unreachable, non-2xx from the target, or the server overriding the requested channel (visible via the appended channel note).
Common situations: Webhook integration deleted after selection; template references fields the payload lacks; target endpoint returns 401/404; server fell back to a different channel because the webhook config was incomplete.
Related errors
- Email reminder was not sent
- ntfy reminder was not sent
- Server error
- data.error || ('HTTP ' + (data.status || 500))
- model returned no rewritten text
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/143e9379c7e97a85.
Report an issue: GitHub.