QuantumNous/new-api · warning · Error
Passkey verification is not available in the current state
Error message
Passkey verification is not available in the current state
What it means
Thrown from the catch in verifyPasskey() when the WebAuthn call rejects with a DOMException named InvalidStateError. The spec defines this for operations on credentials that are in an invalid state — most commonly re-using a credential that is already registered, or the authenticator being in a state that forbids the requested operation. The original exception is kept as cause.
Source
Thrown at web/src/features/auth/secure-verification/api.ts:184
if (!finishResponse.success) {
throw new Error(
finishResponse.message || i18next.t('Passkey verification failed')
)
}
if (!finishResponse.data?.proof_token) {
throw new Error(i18next.t('Verification proof was not returned'))
}
return finishResponse.data
} catch (error: unknown) {
if (error instanceof DOMException && error.name === 'NotAllowedError') {
throw new Error(
i18next.t('Passkey verification was cancelled or timed out'),
{ cause: error }
)
}
if (error instanceof DOMException && error.name === 'InvalidStateError') {
throw new Error(
i18next.t('Passkey verification is not available in the current state'),
{ cause: error }
)
}
throw error
}
}
View on GitHub (pinned to e2c7aa7b10)
Solutions
- Make the passkey button idempotent: disable it while a ceremony is in flight so only one credentials.get() runs.
- Retry once — transient authenticator state usually clears.
- Unplug/replug the security key or re-trigger platform-authenticator availability.
- If persistent, re-register the passkey (the stored credential may be in a bad state server-side).
Example fix
// before
<button onClick={handlePasskey}>Use Passkey</button>
// after
const [busy, setBusy] = useState(false)
<button
disabled={busy}
onClick={async () => {
setBusy(true)
try { await verify('passkey', scope) } finally { setBusy(false) }
}}
>
Use Passkey
</button> Defensive patterns
Strategy: try-catch
Validate before calling
// guard against concurrent ceremonies
if (busyRef.current) return
busyRef.current = true
try {
await verify('passkey', scope)
} finally {
busyRef.current = false
} Type guard
const isInvalidStateError = (e: unknown): boolean => e instanceof DOMException && e.name === 'InvalidStateError'
Try / catch
try {
await verify('passkey', scope)
} catch (e) {
if (isInvalidStateError(e)) {
await sleep(250)
return verify('passkey', scope) // single retry after authenticator settles
}
throw e
} Prevention
- Disable the passkey button while a ceremony is in flight (no double-trigger)
- Retry once after a short delay; transient authenticator state clears itself
- Replug security keys or re-register the passkey if errors persist
When it happens
Trigger: navigator.credentials.get() with an allowList credential whose state is invalid on the authenticator; racing a second credentials.get() while one is pending on some browsers; platform authenticator locked by a prior in-flight ceremony.
Common situations: Double-triggered verification (button double-click firing two ceremonies); security key left in a half-finished state from a previous aborted flow (replug fixes it); browser bug after tab sleep/resume.
Related errors
- Passkey verification was cancelled or timed out
- Passkey verification is not supported in this environment
- Failed to start verification
- Verification flow expired
- Passkey verification was cancelled
AI-assisted analysis of QuantumNous/new-api@e2c7aa7b10 (2026-08-15).
Data as JSON: /api/errors/24e8e69c60d0497a.
Report an issue: GitHub.