Troubleshooting
Two tools answer most questions: getStats() in your app, and the SDK's debug output (debug: true for SDK problems, debug: 'inbound' for webhooks).
import { getStats } from '@theirside/sdk';
const stats = getStats();
if (!stats) console.log('the SDK is off: no apiKey or endpoint, or enabled: false');
else console.log(stats.sent, stats.queued, stats.dropped, stats.lastFlushError);
A provider doesn't show up
- Is the SDK on?
getStats()returnsundefinedwhenapiKeyorendpointis missing: checkTHEIRSIDE_API_KEYandTHEIRSIDE_COLLECTOR_URLreach the process. - Does it send?
sentshould grow after the app has made a few calls, andlastFlushErrorstay undefined. If not, see The collector is unreachable. - Is
init()early enough? In ES modules it must run in a file imported before the rest of your app (Node servers). - Is the host your own? Loopback, private networks, internal names (
*.internal,*.svc, single-label hosts) and telemetry endpoints are never recorded. A partner API on a private address needsproviders: [{ name, hosts }]. - Hidden? Check Settings → Providers for a hidden provider or host.
- Right project and environment? The API key decides the project; the environment picker at the top of the dashboard filters by
environment.
Turn on debug: true to see bad options, flush failures and template overflows in your app's console. Settings → SDK health shows each service and process the collector has heard from.
A webhook isn't discovered
- Start the receiving service with
THEIRSIDE_DEBUG=inbound(ordebug: 'inbound') and send one delivery. The line for it says what happened:recorded as a delivery from …,candidate …, orignored, …with the reason. - No line at all? The request didn't reach a process with the SDK, or
init()ran after the server was created. On AWS Lambda the handler must be wrapped withwrap()(Serverless); other function platforms and Workers don't record incoming requests. ignored, no webhook signal: the request has no route word, signature header, CloudEvents headers or webhook host. Declare the route:webhooks: [{ path, provider }](Webhooks).ignored, browser or front-end request: it carries cookies orOrigin; real webhooks don't.- Recorded, but not in the dashboard? The flush line says whether it was sent (
… to /v1/ingest: 202),held(waiting for the collector to confirm it stores webhooks) ornot sent: timeout. On Lambda, addinbound: true.getStats().inboundshowsheld,sentanddropped. - Ignored in the dashboard earlier? Restore it under Settings → Providers → Discovered webhook routes.
Alerts are too noisy
- The first day: each endpoint learns its normal for 24 hours and uses cautious defaults meanwhile. Webhook silence alerts need three weeks of history.
- An error status that is a normal answer (a
400for "no consent yet"): mark it as expected, in code or from the incident (Expected outcomes). - A provider you don't need alerts for: turn its alerts off on its page or in Settings → Providers; it stays monitored on the dashboard.
- Too sensitive in general, or for one provider: Settings → Thresholds, or the provider's settings, adjust the thresholds.
- Test or staging traffic mixed in: give it its own
environmentso it learns separately.
The collector is unreachable
Your app is never affected: the SDK keeps events in memory up to maxQueue (10,000), drops the oldest beyond that and counts them, and retries with backoff. getStats().lastFlushError says why sending fails:
lastFlushError |
Meaning |
|---|---|
ECONNREFUSED, ENOTFOUND, ETIMEDOUT |
Wrong THEIRSIDE_COLLECTOR_URL, or the network doesn't reach it (security group, DNS, VPN) |
http_401 |
The API key is wrong or revoked: Settings → API keys |
http_413 |
A batch is too large: lower maxBatch |
http_429 |
The project is over its plan's limit |
http_503 |
The collector can't reach its database |
On the collector side: GET /readyz answers 200 when it is ready and 503 while its database is unreachable; its log says why.