Data Migrations
convex-auth owns its own Convex tables, so any data migration over them
runs inside the component. The component ships with the @convex-dev/migrations component mounted internally and exposes runners you trigger from the
CLI after upgrading.
You do not install or configure anything — the migration functions are
part of the auth component once you upgrade the package.
dropHasTotp
Older versions stored a denormalized User.hasTotp boolean (a cache of
“has ≥1 verified TOTP”). It has been removed from the typed surface;
sign-in now resolves TOTP enrollment with an indexed query instead.
The field is still tolerated in the schema so pre-existing rows keep
validating after you upgrade — nothing breaks on deploy. To actually
strip the dead field from existing User documents, run:
npx convex run auth/migrations:runDropHasTotp '{}' - Idempotent — rows without the field are skipped; safe to re-run.
- Batched & resumable — handled by the migrations component; large tables process in batches and resume if interrupted.
- Dry run:
npx convex run auth/migrations:runDropHasTotp '{"dryRun": true}' - Production: add
--prod(npx convex run --prod auth/migrations:runDropHasTotp '{}').
Once every deployment you operate has run this, the hasTotp field will
be removed from the component schema entirely in a future major. Until
then it remains optional and ignored — running the migration is
recommended but not required for the app to function.
Note: this is unrelated to any
User.extendfields your app declares (e.g. a consumer-definedextend.lastActiveGroup). convex-auth never migrates consumerextenddata — that stays under your control.