Skip to content

fix(models): guard identity email against non-string metadata - #2804

Open
suvvvv wants to merge 1 commit into
supabase:masterfrom
suvvvv:fix/identity-nil-email-panic
Open

suvvvv wants to merge 1 commit into
supabase:masterfrom
suvvvv:fix/identity-nil-email-panic

Conversation

@suvvvv

@suvvvv suvvvv commented Sep 15, 2026

Copy link
Copy Markdown

What

NewIdentity in internal/models/identity.go asserted identityData["email"] to a string without checking the type:

if email, ok := identityData["email"]; ok {
    identity.Email = storage.NullString(email.(string)) // panics if not a string
}

identityData is assembled by merging user-supplied signup data metadata into provider.Claims. For a phone signup the email claim is empty and Claims uses structs:"email,omitempty", so it is dropped from the map — which lets a user-supplied data.email that is null (or any non-string) survive into identityData["email"]. The unchecked assertion then panics:

panic: interface conversion: interface {} is nil, not string
  internal/models/identity.go:63  (NewIdentity)
  internal/api/external.go:907    (createNewIdentity)
  internal/api/signup.go:218
  internal/api/otp.go:181 / :91   (SmsOtp → Signup)

The panic happens during identity creation, before any SMS is sent, so the request returns a bare 500 unexpected_failure instead of a meaningful error. This matches the stack trace and the "happens on phone signup / SMS OTP" symptom in the issue.

Fix

Only assign the identity email when the value is actually a string, and apply the same guard to the assertion in BeforeUpdate. A non-string email is ignored (the identities.email column is optional), so signup proceeds normally instead of crashing.

Testing

Added regression coverage in internal/models/identity_test.go for a string email and for non-string values (nil, int, bool, map) that previously panicked. go test ./internal/models/... passes; gofmt and go vet are clean.

Fixes #2268

NewIdentity asserted identityData["email"] to a string without checking
the type. A phone signup omits the empty email claim (structs omitempty),
so a user-supplied `data.email` that is null or otherwise non-string
reaches identityData and panics with "interface conversion: interface {}
is nil, not string", turning a signup/OTP request into a 500.

Only assign the identity email when the value is actually a string, and
apply the same guard in BeforeUpdate. Adds regression coverage.

Fixes supabase#2268
@suvvvv
suvvvv requested a review from a team as a code owner September 15, 2026 10:03

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Panic error in middleware when using Send SMS Hook

1 participant