You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ClerkAPIError drops meta.lockout_expires_in_seconds from user_locked errors #10026
Not needed: the behavior does not depend on an instance, it is in the error parser.
Description
When an account reaches the user lockout threshold, the Frontend API answers the failed attempt with 403 user_locked and includes how long the lockout lasts in meta.lockout_expires_in_seconds. ClerkAPIError builds its meta from a fixed list of known keys (param_name, session_id, identifiers, zxcvbn, plan, …), so lockout_expires_in_seconds is dropped and the app cannot tell the user when they can try again.
Steps to reproduce:
Enable user lockout on an instance (e.g. 10 attempts, 60 minutes).
Sign in with a phone code and submit wrong codes until the attempt returns user_locked.
Inspect the network response: errors[0].meta.lockout_expires_in_seconds is present (e.g. 3599).
Inspect the thrown ClerkAPIResponseError: errors[0].meta has no lockout field.
Expected behavior:
ClerkAPIError.meta exposes the lockout duration (e.g. lockoutExpiresInSeconds), the same way ClerkAPIResponseError.retryAfter already exposes Retry-After for too_many_requests, so apps can show a countdown or hide "resend code" until the lockout ends.
Actual behavior:
The value is discarded during parsing. The only way to read it is to bypass the SDK and parse the raw response.
Environment
@clerk/shared 4.31.0 (also on main as of 2026-10-01)
@clerk/clerk-expo, React Native (Expo SDK), iOS and Android
Confirmed in the source: ClerkAPIError builds meta from a fixed list of keys in packages/shared/src/errors/clerkApiError.ts, so meta.lockout_expires_in_seconds from a user_locked response is dropped. Before touching code, two questions: can you confirm the Frontend API returns that key on user_locked errors, and would you want it exposed as meta.lockoutExpiresInSeconds (camelCase like the other keys)? If yes, I can put up a small PR with a unit test and a changeset.
Activity
deepanshupal commentedon Oct 5, 2026
Confirmed in the source: ClerkAPIError builds meta from a fixed list of keys in packages/shared/src/errors/clerkApiError.ts, so meta.lockout_expires_in_seconds from a user_locked response is dropped. Before touching code, two questions: can you confirm the Frontend API returns that key on user_locked errors, and would you want it exposed as meta.lockoutExpiresInSeconds (camelCase like the other keys)? If yes, I can put up a small PR with a unit test and a changeset.
deepanshupal commentedon Oct 16, 2026
I'm not going to get to a PR for this, so it's free for anyone to take.