koala73/worldmonitor · error

Could not connect email. Please try again.

Error message

Could not connect email. Please try again.

What it means

setEmailChannel() throws this generic fallback when the set-channel API call fails with any error other than the specific EMAIL_OWNERSHIP_REQUIRED code (or when the error body cannot be parsed). It deliberately hides server detail from the user and asks them to retry.

Solutions

  1. Retry the call after a short delay; the error is intentionally generic so transient failures often clear on retry
  2. Inspect the network tab for the actual response status/body to diagnose the underlying cause
  3. Confirm the notifications API is deployed and healthy if failures persist
  4. Validate the email format client-side before the call to rule out request-level rejection

Example fix

// before
await setEmailChannel(email);
// after
try {
  await setEmailChannel(email);
} catch (e) {
  if (e.message.includes('Could not connect email')) {
    await new Promise(r => setTimeout(r, 2000));
    await setEmailChannel(email);
  } else throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email)) { showInvalidEmail(); return; }

Try / catch

try { await setEmailChannel(email); } catch (e) { if (e.message.includes('Could not connect email')) { toast('Retrying…'); await withRetry(() => setEmailChannel(email), 2); } else throw e; }

Prevention

When it happens

Trigger: Calling setEmailChannel(email) and the POST /set-channel request returning non-OK with an unexpected or unparseable error body — network/server 500s, validation failures with unknown codes, gateway errors.

Common situations: Backend outage or 5xx from the notifications API; request rejected with an error code the client doesn't recognize; response body not JSON (proxy/HTML error page); transient network failure mid-request.

Related errors


AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-09-15). Data as JSON: /api/errors/64ca3edb16c1772d. Report an issue: GitHub.

Appendix: source

Thrown at src/services/notification-channels.ts:268

 * nothing the user would miss, and abandoning a popup handoff on teardown is
 * correct.
 */
export async function setEmailChannel(
  email: string,
  expectedUserId?: string,
  signal?: AbortSignal,
): Promise<void> {
  const res = await authFetch('/api/notification-channels', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ action: 'set-channel', channelType: 'email', email }),
  }, expectedUserId, signal);
  if (!res.ok) {
    const failure = await res.json().catch(() => null);
    if (failure?.error === 'EMAIL_OWNERSHIP_REQUIRED') {
      throw new Error('Verify your account email, then try again.');
    }
    throw new Error('Could not connect email. Please try again.');
  }
}

export async function setSlackChannel(
  webhookEnvelope: string,
  signal?: AbortSignal,
): Promise<void> {
  const res = await authFetch('/api/notification-channels', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ action: 'set-channel', channelType: 'slack', webhookEnvelope }),
  }, undefined, signal);
  if (!res.ok) throw new Error(`set slack channel: ${res.status}`);
}

export async function setWebhookChannel(
  webhookUrl: string,
  label?: string,

View on GitHub (pinned to 7d06c8633d)