fix(clerk-webhook): key users row by raw Clerk id (fixes article-create FK) - #210
Conversation
The user.created path created rows with id=`user_${id}`, but Clerk ids are
already `user_…`, so it stored a double-prefixed `user_user_…`. getCurrentUser()
returns the real Clerk id and routes stamp it as a foreign key (posts.authorId
-> users.id), so every user provisioned via this webhook failed posts_authorId_fkey
on article create. Key the row by the Clerk id directly.
Fixes new signups; existing double-prefixed rows need a one-row data repair
(UPDATE users SET id="clerkUserId" WHERE id='user_'||"clerkUserId").
📝 WalkthroughWalkthroughThe Clerk webhook user creation flow now stores the raw Clerk ChangesClerk user provisioning
Estimated code review effort: 2 (Simple) | ~5 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@nextjs_space/app/api/webhooks/clerk/route.ts`:
- Around line 110-115: Update the Clerk webhook provisioning flow around the
users upsert to repair existing email-matched records whose IDs are
double-prefixed as user_user_…, replacing them with the raw Clerk ID before
FK-backed operations proceed. Include this legacy-ID repair as a migration or
documented pre-deployment runbook step, while preserving the new-user behavior
that assigns id: id directly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2c3bb027-5a7c-4791-9942-a9e1005fd474
📒 Files selected for processing (1)
nextjs_space/app/api/webhooks/clerk/route.ts
| // Clerk ids are ALREADY `user_…`. getCurrentUser() returns this id | ||
| // verbatim and routes stamp it as a FK (e.g. posts.authorId → users.id), | ||
| // so the row must be keyed by the raw Clerk id. The old `user_${id}` | ||
| // double-prefixed it (`user_user_…`), so every webhook-provisioned user | ||
| // hit `posts_authorId_fkey` on create. Key by the Clerk id directly. | ||
| id: id, |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the relevant files first
git ls-files 'nextjs_space/app/api/webhooks/clerk/*' 'nextjs_space/app/**' | sed -n '1,200p'
echo
echo '--- outline: route.ts ---'
ast-grep outline nextjs_space/app/api/webhooks/clerk/route.ts --view expanded || true
echo
echo '--- search for users.id / clerk ids / double prefix ---'
rg -n --hidden --no-ignore-vcs 'user_user_|user_\$\{|clerkUserId|users\.id|authorId|getCurrentUser|webhooks/clerk' nextjs_space/app -g '!**/node_modules/**' || trueRepository: AutomatosAI/budstack-saas
Length of output: 14476
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the webhook handler and related user lookups in smaller slices
wc -l nextjs_space/app/api/webhooks/clerk/route.ts
sed -n '1,220p' nextjs_space/app/api/webhooks/clerk/route.ts
echo
echo '--- find user model/schema references ---'
rg -n --hidden --no-ignore-vcs 'clerkUserId|email.*unique|id:\s*id|user_user_|fk|foreign key|authorId' nextjs_space -g '!**/node_modules/**' || trueRepository: AutomatosAI/budstack-saas
Length of output: 50383
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- targeted search for legacy user-id repair ---'
rg -n --hidden --no-ignore-vcs 'user_user_|double-prefixed|repair.*user|user.*repair|clerkUserId.*repair|posts_authorId_fkey|authorId → users.id|raw Clerk id' nextjs_space -g '!**/node_modules/**' || true
echo
echo '--- prisma users model slice ---'
sed -n '530,580p' nextjs_space/prisma/schema.prisma
echo
echo '--- webhook route slice around create/update ---'
sed -n '70,140p' nextjs_space/app/api/webhooks/clerk/route.tsRepository: AutomatosAI/budstack-saas
Length of output: 7831
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Look for any migration/runbook mentioning the required repair step.
rg -n --hidden --no-ignore-vcs 'migration|runbook|repair|backfill|user_user_|clerk webhook|user.created|user.updated|users\.id' nextjs_space/docs nextjs_space/scripts nextjs_space/prisma -g '!**/node_modules/**' || trueRepository: AutomatosAI/budstack-saas
Length of output: 6385
Apply the legacy Clerk-ID repair before shipping.
This fixes only the new-user create path. Any existing user_user_… row that is matched by email will keep the wrong users.id, so FK-backed creates from that account will still fail until the row is updated to the raw Clerk id. Add the repair as a migration or runbook step before deployment.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@nextjs_space/app/api/webhooks/clerk/route.ts` around lines 110 - 115, Update
the Clerk webhook provisioning flow around the users upsert to repair existing
email-matched records whose IDs are double-prefixed as user_user_…, replacing
them with the raw Clerk ID before FK-backed operations proceed. Include this
legacy-ID repair as a migration or documented pre-deployment runbook step, while
preserving the new-user behavior that assigns id: id directly.
The Clerk
user.createdwebhook createdusersrows withid: \user_${id}`. Clerk ids already start withuser_, so this stored a **double-prefixed** id (user_user_…`).getCurrentUser()returns the real Clerk id, and routes stamp it as a foreign key (e.g.posts.authorId → users.id). So any user provisioned through this webhook failsposts_authorId_fkeywhen creating an article — while manually-seeded users work fine.Fix: key the row by the Clerk id directly (
id: id).Note: this fixes new users. Existing double-prefixed rows need a one-row data repair (their
clerkUserIdcolumn already holds the correct id).Summary by CodeRabbit