No silent default account

A write that forgets to say which account it belongs to now fails loudly instead of quietly landing in the first customer's data.

What it is

Migration 049 dropped the column default on org_id across every account-scoped table while keeping NOT NULL, so an insert that omits the account id throws a constraint violation in development and production alike. In the same spirit, the server auth layer stopped returning the original account as a fallback for anyone but the platform owner.

Also called: org_default · rows landed in the wrong account · default tenant · NOT NULL org_id

See it
No silent default account
Area
Platform & Admin
Group
Tenancy & isolation
System
Multi-Tenancy & Identity
Solves
3 named problems
01Migration 013 originally added org_id with a default pointing at the first account, in order to backfill legacy rows.
02Migration 049 removes that default everywhere while keeping the column NOT NULL.
03audit_log.org_id becomes nullable instead, because some platform events legitimately have no account — the signup webhook fires before the user is attached to anything.
A before/after of an INSERT: left silently stamped with the default account, right rejected by a NOT NULL violation. supabase-migrations/049_drop_org_id_defaults.sql. Sample data — no customer information appears here.
How it works
  1. 1Migration 013 originally added org_id with a default pointing at the first account, in order to backfill legacy rows.
  2. 2Migration 049 removes that default everywhere while keeping the column NOT NULL.
  3. 3audit_log.org_id becomes nullable instead, because some platform events legitimately have no account — the signup webhook fires before the user is attached to anything.
  4. 4serverAuth returns null rather than the default account for a non-owner with no resolvable account, and the request 401s.
  5. 5The org resolution cache stores negative results too, so a missing mapping doesn't hammer the database.
Why we built it

The migration header is the clearest statement of intent in the codebase: the default 'silently stamps the row to org_default… We've been finding and fixing these one at a time.' It accepts the consequence in advance — 'there may be write paths we haven't found that omit org_id. Those will start throwing 500s as soon as this lands. That's the whole point — silent poisoning is worse than a visible error.' serverAuth carries the matching note: the silent default 'silently dropped other tenants' users onto [the first tenant's] data when their session was missing the Clerk org claim (a frequent state on the apex host).'

The problem
  • A column default meant any forgotten account stamp landed in a real customer's data with no error.
  • A missing session claim silently routed a user into the wrong account instead of failing.
  • Repeated misses against a missing mapping hammered the database.
Sound familiar?
What you get
A miswritten row fails immediately instead of poisoning another account.
A user with no resolvable account gets an error, never someone else's dashboard.
Platform-level events can be recorded honestly as belonging to no account.

See it on your own jobs

Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.

or keep browsing features →