Prompt-Led Product | For PMs Building in the AI Era

Prompt-Led Product | For PMs Building in the AI Era

Your Guest Invites Are Silently Breaking. Here Is the Fix.

How I stopped manually reconnecting invited users after sign-up, and the 12-line Postgres trigger that does it automatically now.

Elena | AI Product Leader's avatar
Elena | AI Product Leader
Jun 02, 2026
∙ Paid

Check out the Build Series. Part 1 | Part 2 | Part 3 | Part 4 | Part 5

If your product allows off-platform invites, at least some of your invited users are landing on an empty dashboard after sign-up — not knowing their access already exists. Most builders never notice because the user just silently disappears rather than reporting it.

The week I shipped Writer’s Room on DraftKit, I added multi-guest support to collaboration workspaces. A host could invite up to 5 collaborators by email. The email went out, the row got written to workspace_collaborators, and I thought that was it.

It was not it.

Three days later, I had 4 messages in my inbox. Each one was some version of: “I signed up from your invite email, but my dashboard is empty. Did something go wrong?”

I checked the database.

Their rows were sitting in workspace_collaborators, linked to their email address. But the user_id column was null. The invite existed. The account existed.

The two had never met.

I had built a collaboration product where an invited guest, after following an email and completing sign-up, landed on a blank screen. This is the specific gap that kills invited-user activation: the window between “invite sent” and “account created” creates an orphaned record that most apps never resolve.

Why Four Users Emailed Me the Same Thing in Three Days

Your invitation is stored linked to an email address. Your auth system creates user accounts with UUIDs. Those are two different identifiers, and nothing connects them automatically. When an invited user signs up, their new UUID gets created with no lookup for pending invitations tied to their email. The two records sit there independently until you build the bridge.

Userpilot’s 2024 Product Metrics Benchmark Report puts average SaaS activation at 37.5%. That is already a low bar. For invited users, the expectation is higher: they clicked a link, they came with intent, they completed sign-up. The product owes them a working experience immediately. A blank dashboard is not a soft failure. It is a conversion cliff.

The pattern is the same everywhere. Any Supabase product, any Postgres-backed product, any system using UUID-based auth while sending email invitations is exposed to this. The fix is a trigger, not a feature.

Why Your Workflow Misses This

Most builders design the invite flow from the sender’s side. You write the row. You send the email. You move on.

The gap lives on the receiver’s side, and specifically in the timing mismatch. Your invite row exists in the database, linked to an email address. The guest’s UUID does not exist yet. By the time they create an account, nothing in your system is looking backward at the invitation table to make the connection.

The fix is not a cron job, not a manual process, not a support ticket. It is a database trigger that fires the moment a new auth account is created.

Share

The Approach I Follow

✅ Write the invitation to the database immediately, linked to email only. Store the row with the guest’s email and a null user_id. The invitation exists from the moment it is sent, not from the moment they sign up.

✅ Build the trigger before you ship the invite feature. This is the part I got wrong. I shipped Writer’s Room before I built the reconciliation logic. The correct sequence: design the data model, write the trigger, test it, then ship the invite flow.

✅ Scope the trigger to run on new user creation only. Fire it on INSERT to your auth users table, look up pending records by email, and update the user_id column atomically.

✅ Set joined_at in the same operation. Do not leave that column null after linking. You want to know when the guest first became a participant, not just that they eventually did.

✅ Run a one-time backfill after deploy. If you have existing orphaned rows, and if you have an invite feature that is more than a few weeks old, you do then run a manual UPDATE query at deploy time to link any rows that the trigger will not touch retroactively.

This post is for paid subscribers

Already a paid subscriber? Sign in
© 2026 © 2026 Elena Calvillo | AI Product Leader · Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture