What's in place
RemixCRM ships with two layers of error capture out of the box:
bug_reportstable + auto-error-report endpoint — uncaught React-tree errors show up automatically. See Automatic error reports.- Structured logger in
lib/log.ts— every server call writes grep-able lines to Railway logs.
The new third layer is Sentry — captures errors from every Next.js layer (server components, API routes, server actions, middleware, client) with full stack traces, source maps, deduplication, and email alerts.
Setting up Sentry (one-time)
1. Create the project
- Sign up at sentry.io — free tier covers 5,000 events/month
- Create a new project: pick Next.js as the platform
- Note three values you'll need:
- DSN (looks like
https://abc123@o123.ingest.sentry.io/456) - Org slug (in the URL:
sentry.io/organizations/<slug>/) - Project slug (the name you gave the project)
- DSN (looks like
2. Generate a source-map upload token
Source maps make stack traces actually readable (file:line instead of minified
gibberish like chunks/abc.js:1:2535).
- In Sentry: Settings → Auth Tokens → Create new token
- Name it "Railway build" or similar
- Scopes: at minimum
project:releasesandorg:read - Copy the token (shown once)
3. Add to Railway
Go to Railway → RemixCRM service → Variables → + New Variable:
| Variable | Value |
|---|---|
SENTRY_DSN |
Server DSN |
NEXT_PUBLIC_SENTRY_DSN |
Same DSN — exposed to the browser (this is fine, DSNs are public identifiers) |
SENTRY_ORG |
Org slug |
SENTRY_PROJECT |
Project slug |
SENTRY_AUTH_TOKEN |
Auth token from step 2 |
Railway redeploys automatically. Source maps upload on next build.
4. Set up email alerts
In Sentry: Alerts → Create alert rule.
| Setting | Value |
|---|---|
| When | A new issue is created OR an issue's frequency changes by more than 100% |
| Send to | Email → support@remixcrm.com |
| Filter | Environment = production only (so dev errors don't spam you) |
5. Verify it's working
After the next Railway deploy, hit your app and trigger a test error. The easiest test: open the browser console on any logged-in page and run:
throw new Error('Sentry test — please ignore')
You should see the error in Sentry within ~30 seconds, with a full stack trace, browser info, and user/org identifiers (if you're logged in).
How it integrates with what we already have
| Layer | Captured by | Best for |
|---|---|---|
| Server-action / API throws | Sentry + Railway logs | Server-side errors, performance issues |
| React-tree uncaught | Sentry + bug_reports (auto) + Railway logs |
Client-side crashes |
| User-reported issues | bug_reports (via support chat) |
Bugs the user can describe |
| Performance regressions | Sentry (traces) | "Why is /events suddenly slow?" |
| Build failures | Railway only | CI surface |
Sentry becomes the primary console for code errors. bug_reports stays for
user-initiated triage conversations.
Tier 2 — AI-generated PR fixes (optional)
There's also a GitHub Actions workflow at .github/workflows/ai-fix.yml
that can open draft PRs with proposed fixes when Sentry alerts fire.
How it works:
- Sentry detects a new issue
- Sentry posts a webhook to GitHub (
repository_dispatchevent) - The workflow runs
scripts/ai-fix.mjswhich:- Reads the issue payload
- Asks the configured AI assistant for a minimal fix
- Applies the patch on a new branch
- Typechecks the result
- Opens a draft PR (never auto-merges)
- You review, approve, and merge. CI runs as a final gate.
Required GitHub secrets:
ANTHROPIC_API_KEY— AI provider API keyGH_PR_TOKEN(optional, recommended) — fine-grained PAT withpull-requests: writeandcontents: writescopes, used to trigger CI on the PR
Required Sentry webhook config: In Sentry → Settings → Integrations → Webhooks, add a webhook pointing at:
https://api.github.com/repos/<owner>/<repo>/dispatches
with payload:
{
"event_type": "sentry-issue",
"client_payload": {
"issue_url": "$ISSUE_URL$",
"title": "$ISSUE_TITLE$",
"message": "$ISSUE_MESSAGE$",
"culprit_file": "$ISSUE_CULPRIT$"
}
}
Authentication uses a GitHub personal access token in the Authorization: Bearer header.
Safety guarantees:
- Never pushes to
maindirectly - Always opens a draft PR
- Typechecks the patch before committing
- The assistant is instructed to output
<skip>if it can't make a confident fix - Hard rules in the system prompt prevent it from touching migrations, package.json, or dependencies
Risks worth knowing:
- The assistant can produce wrong fixes that nonetheless typecheck. Human review is essential.
- The cost adds up if a single error fires repeatedly — Sentry's dedup helps but isn't perfect.
- Disable this workflow if it's churning out bad PRs faster than you can close them.
Testing the AI-fix workflow manually
You can trigger it without a real Sentry alert:
gh workflow run ai-fix.yml \\
-f issue_url='https://sentry.io/test' \\
-f title='Test error — null clientId in convertLeadToEvent' \\
-f message='TypeError: Cannot read properties of null (reading id)' \\
-f culprit_file='app/(app)/leads/actions.ts'
The workflow will run, the assistant will read app/(app)/leads/actions.ts, propose a
fix (or skip), and open a PR if one was produced. Use this to verify the wiring
before a real alert fires.