Skip to content
Latchkey

Knex "Migration table is already locked" in CI

Knex takes a row in knex_migrations_lock so two migration runs cannot proceed at once. If a previous run was killed before releasing it, the lock stays set and the next run reports "already locked" - or two runs genuinely overlap.

What this error means

knex migrate:latest fails with "Migration table is already locked", often after a cancelled or OOM-killed CI job, or when two jobs migrate the same database concurrently.

psql
Knex: Error
Migration table is already locked
MigrationLocked: Migration table is already locked

Common causes

Stale lock from a killed run

A cancelled, timed-out, or OOM-killed run never released the lock, so knex_migrations_lock stays locked and blocks the next run.

Concurrent migration runs

Two pipelines migrating the same database at once legitimately contend for the lock.

How to fix it

Release a stale lock

When no other migration is running, unlock so the next run can proceed.

Terminal
npx knex migrate:unlock
npx knex migrate:latest

Serialize migrations

  1. Use a CI concurrency group so only one migration job runs against a database at a time.
  2. Avoid two pipelines targeting the same database concurrently.
  3. Set a step timeout so a stuck lock surfaces fast.

How to prevent it

  • Constrain migration jobs with a concurrency group so they cannot overlap.
  • Clear stale locks at the start of a controlled, single-writer migration.
  • On managed runners (Latchkey), self-healing auto-retries transient lock-contention failures so a briefly-held lock can clear.

Frequently asked questions

What causes ""Migration table is already locked""?
A cancelled, timed-out, or OOM-killed run never released the lock, so knex_migrations_lock stays locked and blocks the next run.
How do I fix "Migration table is already locked"?
When no other migration is running, unlock so the next run can proceed.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card