koala73/worldmonitor · error · ApiError

Webhook registration could not be confirmed

Error message

Webhook registration could not be confirmed

What it means

registerWebhook performs three Redis-backed registration steps (subscriber registration, owner-index add, and a final confirmation write) via Promise.all and inspects each result. If any step errors, returns an unexpected shape, or the confirmation codes are not the expected 'OK' / 0|'0' / 1|'1' values, it throws HTTP 503 'Webhook registration could not be confirmed' — the registration is treated as not committed.

Solutions

  1. Retry the registration with a new subscriberId after a short backoff — a partial registration expires via WEBHOOK_TTL
  2. Verify webhook data-store health (Redis connectivity, latency, error rates) before repeated attempts
  3. Confirm your subscriberId/secret handling tolerates re-registration (idempotent setup scripts)
  4. If it reproduces consistently, check for Redis script/version drift; the expected confirmation codes are 'OK', 0|'0', and 1|'1'

Example fix

// before
const { subscriberId, secret } = await client.registerWebhook({ callbackUrl });
// after
let reg;
try {
  reg = await client.registerWebhook({ callbackUrl });
} catch (e) {
  if (e.status === 503) reg = await retryWithBackoff(() => client.registerWebhook({ callbackUrl }));
  else throw e;
}
Defensive patterns

Strategy: retry

Try / catch

try {
  reg = await client.registerWebhook({ callbackUrl });
} catch (e) {
  if (e.status === 503 && /could not be confirmed/.test(e.message)) {
    reg = await retryWithBackoff(() => client.registerWebhook({ callbackUrl }), { retries: 3 });
  }
  throw e;
}

Prevention

When it happens

Trigger: Any of the three Redis operations failing or returning malformed results during register-webhook: Redis unavailable, a script returning an unexpected value, TTL/TTL-type mismatch, or partial failure across the batch.

Common situations: Upstash/Redis transient errors or timeouts; cluster failover mid-write; Redis version/script incompatibility producing different result encodings; network blips between the API worker and Redis.

Related errors


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

Appendix: source

Thrown at server/worldmonitor/shipping/v2/register-webhook.ts:124

    callbackUrl,
    chokepointIds: chokepointIds.length ? chokepointIds : [...VALID_CHOKEPOINT_IDS],
    alertThreshold,
    createdAt: new Date().toISOString(),
    active: true,
    secret,
  };

  const results = await runRedisPipeline([
    ['SET', webhookKey(newSubscriberId), JSON.stringify(record), 'EX', String(WEBHOOK_TTL)],
    ['SADD', ownerIndexKey(ownerTag), newSubscriberId],
    ['EXPIRE', ownerIndexKey(ownerTag), String(WEBHOOK_TTL)],
  ]);

  if (!Array.isArray(results) || results.length !== 3 || results.some(result => !result || result.error)
    || results[0]?.result !== 'OK'
    || ![0, 1, '0', '1'].includes(results[1]?.result as number | string)
    || (results[2]?.result !== 1 && results[2]?.result !== '1')) {
    throw new ApiError(503, 'Webhook registration could not be confirmed', '');
  }

  return { subscriberId: newSubscriberId, secret };
}

View on GitHub (pinned to 7d06c8633d)