Skip to content

Fix Knex Migrate Latest – Migration Not Applying

DodaTech Updated 2026-06-24 3 min read

In this tutorial, you'll learn about Fix Knex Migrate Latest. We cover key concepts, practical examples, and best practices.

You run npx knex migrate:latest and get "Already up to date" — but you just added a migration file. Or the command fails with "migration directory is empty" when the directory has files.

Wrong ❌

npx knex migrate:latest

Output:

Already up to date

But `migrations/20240624000001_add_phone.ts` exists and hasn't been applied. Knex doesn't see it.

## Right ✅

```<a href="/programming-languages/javascript/">javascript</a>
// knexfile.js
module.exports = {
  development: {
    client: '<a href="/databases/postgresql/">postgresql</a>',
    connection: {
      host: 'localhost',
      database: 'mydb',
      user: 'postgres',
      password: 'password',
    },
    migrations: {
      directory: './migrations',         //  must match actual path
      extension: 'ts',                   // or 'js'
      tableName: 'knex_migrations',      // default table name
    },
    pool: {
      min: 2,
      max: 10,
    },
  },
};

```bash
# Check the migration status
npx knex migrate:status

# Output:
# Migration                                   Status
# 20240601000000_create_users.ts               up
# 20240624000001_add_phone.ts                  down   ← pending

**If `migrate:status` shows it as `down` but `migrate:latest` says "up to date":**

The extension might be wrong. If the file is `.ts` but the config expects `.js`:

```bash
# Force the extension
npx knex migrate:latest --knexfile knexfile.js --ext ts

**Or the migration file might have an error:**

```bash
# Try running the migration directly
npx knex migrate:up 20240624000001_add_phone.ts

**Create a proper migration file:**

```bash
npx knex migrate:make add_phone

```typescript
// migrations/20240624000001_add_phone.ts
import { Knex } from 'knex';

export async function up(knex: Knex): Promise<void> {
  await knex.schema.alterTable('users', (table) => {
    table.string('phone', 20).nullable();
  });
}

export async function down(knex: Knex): Promise<void> {
  await knex.schema.alterTable('users', (table) => {
    table.dropColumn('phone');
  });
}

**If the `knex_migrations` table is missing:**

```bash
npx knex migrate:latest
# Automatically creates the knex_migrations table on first run

**If the migration fails with "column already exists":**

```bash
# The migration was partially applied. Mark it as done:
npx knex migrate:up 20240624000001_add_phone.ts
# If it fails, edit the migration or manually update knex_migrations:
# UPDATE knex_migrations SET migrated_at = NOW() WHERE name = '...';

**Debug with verbose logging:**

```bash
npx knex migrate:latest --debug

## Root Cause

Knex compares migration files against the `knex_migrations` table. If the file extension in the config doesn't match the actual files, or the directory path is wrong, Knex treats the directory as empty. Also, if a migration file has a syntax error, Knex may skip it silently.

## Prevention

- Use `knex migrate:make` to create migrations — it produces the correct format.
- Match the `extension` config to your file type (`.ts` or `.js`).
- Run `knex migrate:status` before `knex migrate:latest` to see pending migrations.
- Use `cjs` or `.mjs` extensions if needed (CommonJS vs ESM).


## Common Mistakes with migrate latest

1. **Using `foldl` instead of `foldl'` causing stack overflow on large lists**
2. **Forgetting `deriving (Show, Eq)` on custom data types needed for debugging**
3. **Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable**

These mistakes appear frequently in real-world KNEX code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

## Practice Exercise

**Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.**

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

## FAQ

<details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">**Q: How do I undo the last migration?**</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>A: <code>npx knex migrate:rollback</code>.</p>
</div></details><details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">**Q: What's the difference between `migrate:latest` and `migrate:up`?**</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>A: <code>latest</code> runs all pending migrations. <code>up</code> runs the next pending one.</p>
</div></details><details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">**Q: Can I use Knex with <a href="/programming-languages/typescript/">TypeScript</a> migration files?**</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>A: Yes  set <code>extension: 'ts'</code> and use <code>ts-node</code> or <code>tsx</code> to run them.</p>
</div></details><details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">**Q: How do I seed data after migration?**</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>A: Use <code>knex seed:run</code>. Put seed files in <code>seeds/</code> directory.</p>
</div></details>

---

*Knex migrations are covered in the [DodaTech Knex.js Database Toolkit course](https://dodatech.com/courses/knex).*

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro