Skip to content

npx vendure migrate --run silently no-ops (exits 0, ~3s) instead of running pending migrations #5001

Description

@almesbahi

Describe the bug

Running npx vendure migrate --run with pending migrations present exits 0 after roughly 3 seconds without applying anything, printing no error and no indication that no migrations ran. It looks identical to a successful "already up to date" run, so it silently masks a database that is out of sync with the entity schema.

To Reproduce

  1. In a Vendure project with @vendure/cli installed, add a new TypeORM migration file under the configured migrations glob (e.g. src/migrations/) that has not yet been applied to the target database.
  2. Run npx vendure migrate --run.
  3. Observe: the command exits 0 in ~3s.
  4. Inspect the migrations table in the database, or re-run a schema diff — the new migration was never applied.

Expected behavior

The command should apply the pending migration(s), print which migration(s) were run, and exit 0. If it cannot run for any reason (e.g. a config-loading failure), it should exit non-zero and print an error, not silently no-op.

Actual behavior

The process exits 0 almost immediately, with no log output indicating a migration ran or was skipped, and the pending migration remains unapplied.

Root cause (as diagnosed)

Tracing the CLI, the process dies during config-loading — before it ever reaches runMigrationsOperation() — and this failure is swallowed rather than surfaced. The suspected culprit is the @vendure/dashboard package's .d.ts files being picked up under Node's native TS-stripping (--experimental-strip-types-style loading) when the CLI loads vendure-config.ts; something in that load path throws or returns early, and the CLI's error handling for that path is missing or non-fatal, so it falls through to a clean exit instead of propagating the error.

Note: npx vendure migrate --revert exhibits the same silent no-op behavior, for the same reason (it goes through the same config-loading path before reaching its migration operation).

Workaround

Bypass the vendure CLI entirely and run migrations via a raw TypeORM DataSource:

// scripts/run-migrations-raw.ts
import 'dotenv/config';
import path from 'path';
import { DataSource } from 'typeorm';

async function main() {
    const dataSource = new DataSource({
        type: 'postgres',
        host: process.env['DB_HOST']!,
        port: +(process.env['DB_PORT'] ?? 5432),
        username: process.env['DB_USERNAME']!,
        password: process.env['DB_PASSWORD']!,
        database: process.env['DB_NAME']!,
        migrations: [path.join(__dirname, '../src/migrations/*.+(js|ts)')],
        logging: true,
    });

    await dataSource.initialize();
    try {
        const applied = await dataSource.runMigrations();
        console.log(`Applied ${applied.length} migration(s):`, applied.map(m => m.name));
    } finally {
        await dataSource.destroy();
    }
}

main().catch(err => {
    console.error(err);
    process.exit(1);
});

Run with npx ts-node scripts/run-migrations-raw.ts (or equivalent). This correctly applies pending migrations and records them in the migrations table, confirming the migrations themselves are valid and the bug is isolated to the CLI wrapper, not to TypeORM or the migration files.

Environment (please complete the following information):

  • @vendure/core version: 3.7.1 (also @vendure/cli 3.7.1, @vendure/dashboard 3.7.1)
  • Nodejs version: v22.22.3
  • Database (mysql/postgres etc): PostgreSQL 17.10
  • Operating System (Windows/macOS/Linux): reproduced on both macOS (local dev, Darwin 25.5.0) and Linux (Ubuntu 24.04 LTS, production/staging server)
  • Browser (if applicable): N/A (CLI issue)
  • Package manager (npm/yarn/pnpm): npm

Additional context

  • Every migration file's header comment that cites npx vendure migrate --run as the way to verify/apply it is currently misleading, since the command does not reliably do what it claims.
  • This is a correctness/data-safety issue, not just a DX annoyance: a silent no-op that looks like success can leave a production database out of sync with entity definitions with no visible warning.
  • Would like a root-cause fix (either the config-loading failure should be fixed, or at minimum the CLI should fail loudly instead of silently exiting 0) before trusting the vendure migrate CLI path again, especially against staging/production databases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T2: Elevated riskTouches critical paths or has wide blast radius. Needs careful, owned work.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions