Skip to content

fix(sentry): null-coalesce PostgREST details/hint to prevent TypeError#945

Merged
sw-factory-automations merged 1 commit intomainfrom
fix/sentry-memo-2e-null-postgrest-details
May 7, 2026
Merged

fix(sentry): null-coalesce PostgREST details/hint to prevent TypeError#945
sw-factory-automations merged 1 commit intomainfrom
fix/sentry-memo-2e-null-postgrest-details

Conversation

@sw-factory-automations
Copy link
Copy Markdown
Collaborator

Summary

PostgREST 500 responses return details: null and hint: null. The isPostgrestError duck-type check uses the in operator, which returns true when the key exists regardless of value type. Calling null.startsWith() or null.includes() in isTransientNetworkError and isSupabaseAuthLockError crashes the retry logic, turning a retryable Supabase 500 into an unhandled rejection that crashes the page.

Sentry issue: https://ona-2j.sentry.io/issues/MEMO-2E — 2 events, 1 user, unhandled.

Closes #944

Root Cause

  1. Supabase returns HTTP 500 for a pages query
  2. retryOnNetworkError() calls isTransientNetworkError(result.error)
  3. isPostgrestError() returns true (all 4 keys exist on the error object)
  4. error.details is null (PostgREST 500 response)
  5. null.startsWith()TypeError: Cannot read properties of null (reading 'startsWith')

Changes

  • src/lib/sentry.ts: Update isPostgrestError type guard to reflect that details and hint can be null. Add ?? "" null coalescing in isTransientNetworkError, isSupabaseAuthLockError, and captureSupabaseError.
  • src/lib/sentry.unit.test.ts: Add regression tests for PostgREST errors with details: null and hint: null across all three affected functions.
  • .agents/conventions.md: Document the null-safety convention for PostgREST fields.

Testing

  • pnpm lint — 0 errors
  • pnpm typecheck — passes
  • pnpm test — 1812 tests pass (132 files)

PostgREST 500 responses return `details: null` and `hint: null`.
The `isPostgrestError` duck-type check uses the `in` operator which
returns true when the key exists regardless of value type. Calling
`null.startsWith()` or `null.includes()` in `isTransientNetworkError`
and `isSupabaseAuthLockError` crashes the retry logic, turning a
retryable Supabase 500 into an unhandled rejection.

- Update `isPostgrestError` type guard to reflect nullable fields
- Add `?? ""` null coalescing in isTransientNetworkError,
  isSupabaseAuthLockError, and captureSupabaseError
- Add regression tests for null details/hint
- Document null-safety convention in .agents/conventions.md

Closes #944

Co-authored-by: Ona <no-reply@ona.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 7, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
memo Ready Ready Preview, Comment May 7, 2026 7:22pm

Request Review

@sw-factory-automations sw-factory-automations merged commit df55b60 into main May 7, 2026
6 checks passed
@sw-factory-automations sw-factory-automations deleted the fix/sentry-memo-2e-null-postgrest-details branch May 7, 2026 19:27
@sw-factory-automations
Copy link
Copy Markdown
Collaborator Author

✅ UI verification skipped — no UI files changed. This PR only modifies src/lib/sentry.ts (utility logic), its unit tests, and .agents/conventions.md (documentation).

@sw-factory-automations
Copy link
Copy Markdown
Collaborator Author

✅ Post-merge verification passed.

E2E tests against live site (https://memo.software-factory.dev):

  • e2e/auth.spec.ts — 8/8 passed (sign-in, sign-up, sign-out, redirects)
  • e2e/page-crud.spec.ts — 5/5 passed (create, navigate, rename, delete pages)
  • e2e/database-crud.spec.ts — 11/11 passed (create DB, add columns, edit cells, delete rows/columns, undo)

Ad-hoc smoke tests:

  • ✅ Landing page — loads, has title
  • ✅ Sign-in page — renders with email input
  • ✅ Health endpoint (/api/health) — returns OK
  • ✅ Authenticated flow — login succeeds, workspace page loads
  • ✅ No console errors (unauthenticated or authenticated)

Skipped:

  • /dashboard (route does not exist — 404)
  • Editor navigation (no page buttons with timestamps found in test workspace)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working status:in-progress

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: null PostgREST details field crashes isTransientNetworkError and isSupabaseAuthLockError (Sentry MEMO-2E)

1 participant