MainSDK
Search⌘K
How-to

Know when your app breaks before your users tell you

Capture every unhandled error, group it under a stable fingerprint, get alerted when a group is new or spiking, and send events to OpenTelemetry or Sentry.

Planned for 0.4

Status Status is where the work is: Planned (in a milestone, not started), Building (tickets in progress), Preview (usable, may change), then the stability it ships at.

Stability The promise an interface ships with.

  • Stable Follows semantic versioning; breaking changes need a new major, 12 months of overlap and a codemod.
  • Beta Usable in production; may change before it becomes stable.
  • Experimental May change or go away; needs an explicit opt-in in main.yaml.
Stability levels
Updated 2026-10-28

You will make an app capture every unhandled error, group it so one bug is one group, alert when a group is new in a release or spikes, and read the groups from the terminal. It takes about 10 minutes and needs no SDK from an error tracker.

You need

  • A MainSDK app with a main.yaml, behind one of the adapters (mainsdk/hono, mainsdk/next or mainsdk/express).
  • Optional: an OpenTelemetry collector, or a Sentry project and its DSN.

1. Do nothing and read the groups

Errors are captured and grouped as soon as the adapter runs. Under mainsdk dev they are also written to the local event store:

bash
npx mainsdk errors --since 1h

Each row is a fingerprint, a count, the last time it happened and whether it is new in this release.

2. Send the events somewhere

main.yaml
network:
  allow: [o1.ingest.sentry.io]
logging:
  errors:
    driver: sentry
    dsn: secret:SENTRY_DSN

Use driver: otlp to send an OpenTelemetry exception event through telemetry.otel instead. Sending never delays a request: events wait in a bounded queue, and when the destination is down they are dropped with one MAIN-REPORT-0003 record per outage. mainsdk check reports MAIN-REPORT-0005 for a sentry driver with no dsn or a host missing from network.allow.

3. Get told about new and spiking errors

main.yaml
logging:
  errors:
    alert:
      new: warning
      spike: { over: 50, per: 5m, severity: critical }

A group that first appears in this release raises error:<fingerprint> once across all instances when a kv section is declared. A group that passes 50 events in 5 minutes raises error-spike:<fingerprint> and resolves when the window empties. Both go through the routes you set in alerts.

4. Report browser errors

Set logging.errors.browser: true, then in the page:

app/client.ts
import { reportErrors } from "mainsdk/log/client";

reportErrors();

Reports are limited to 16 KB and 10 a minute per session or address, and the page's query and fragment are removed.

What is never sent

Every event is redacted in process first: secret values, key formats, emails, tokens and phone numbers in the message, and file paths relative to the project. No request body, header, cookie, query value or environment value is read. A signed-in request adds only an opaque hash of the user id.

Next

Was this page helpful?

↑↓ moveEnter openEsc close

Not decided yet