Skip to content
Latchkey

Knex "Migration table is already locked" in CI

Knex sets a row in knex_migrations_lock before running migrations and clears it after. If a run is killed mid-migration, the lock stays set, and the next run fails because the migration table is already locked.

What this error means

knex migrate:latest fails with "Migration table is already locked. If you are sure migrations are not running you can release the lock manually..." after a cancelled or crashed run.

knex output
Knex: Migration table is already locked.
If you are sure migrations are not running you can release the lock manually by deleting
all the rows from migrations lock table: knex_migrations_lock

Common causes

A previous migration run was killed

A cancelled or timed-out CI job died while holding the lock, leaving knex_migrations_lock set to locked.

Two migration runs overlapped on the same database

Concurrent jobs against one database collide on the lock row.

How to fix it

Release the stale lock

When no migration is running, clear the lock and re-run. Recent Knex also exposes a force-unlock command.

Terminal
npx knex migrate:unlock
npx knex migrate:latest

Avoid overlapping runs

  1. Run only one migration job per database.
  2. For disposable CI databases, recreate the database instead of unlocking.
  3. Add timeouts so a hung run does not hold the lock.

How to prevent it

  • Run a single migration job per database.
  • Use fresh databases in CI so locks never persist.
  • Unlock only when you are sure no migration is in progress.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →