medusajs/medusa · error · MedusaError
Verification code is invalid or already used
Error message
Verification code is invalid or already used
What it means
The verification token lookup either found no matching record or found one already consumed (verified_at set). Codes are single-use, so reuse or wrong codes are both rejected with NOT_ALLOWED.
Source
Thrown at packages/modules/auth/src/providers/verification/token.ts:119
if (!data.code) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"Verification code is required"
)
}
const [verification] = await this.authVerificationService_.list(
{
provider_metadata: {
token_hash: hashVerificationToken(data.code),
},
},
{},
sharedContext
)
if (!verification || verification.verified_at) {
throw new MedusaError(
MedusaError.Types.NOT_ALLOWED,
"Verification code is invalid or already used"
)
}
if (
data.code_provider &&
data.code_provider !== verification.code_provider
) {
throw new MedusaError(
MedusaError.Types.NOT_ALLOWED,
`Verification code does not belong to provider "${data.code_provider}"`
)
}
const expiresAt =
new Date(verification.requested_at).getTime() + this.getTokenTtlMs_()
View on GitHub (pinned to 5e06e544a2)
Solutions
- Request/generate a new verification code and confirm once with it
- Disable the submit button after first click to prevent double confirmation
- Verify the code string is passed exactly as delivered (no whitespace/encoding issues)
Defensive patterns
Strategy: validation
Validate before calling
// guard against double-submit
if (confirming) return
setConfirming(true)
try { await confirm(...) } finally { setConfirming(false) } Try / catch
try { await confirm(...) } catch (e) { if (e.message.includes('invalid or already used')) { /* request new code */ } throw e } Prevention
- Disable submit button after first click
- Treat confirmation as one-shot: on failure, always re-request a code
When it happens
Trigger: confirm() with a code that doesn't match any verification record, or confirming the same verification twice — the second call sees verified_at set and throws.
Common situations: Double-submitting the confirm form; retrying after a timeout when the first confirm succeeded; user typing the code wrong; expired/rotated token.
Related errors
- Verification code is required
- Verification code does not belong to provider "${data.code_p
- Verification code has expired
- Invalid MFA challenge code
- Invalid MFA verification code
AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27).
Data as JSON: /api/errors/7e1da372e03b59ea.
Report an issue: GitHub.