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

  1. Inspect data.webhook_error and data.channel in the response body
  2. Verify the chosen integration id still exists and its URL responds
  3. Test the target endpoint directly with the rendered payload
  4. 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

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


AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14). Data as JSON: /api/errors/143e9379c7e97a85. Report an issue: GitHub.