Quantcast
Channel: Active questions tagged ubuntu - Stack Overflow
Viewing all articles
Browse latest Browse all 7074

Knex.js migrate:latest fails with “relation knex_migrations already exists” despite table having been dropped

$
0
0

Background

I’m setting up Knex migrations on a PostgreSQL database running inside WSL2 (Ubuntu). My Node.js/Knex app (also in WSL) connects over the WSL IP to this Postgres instance. Everything appears configured correctly, but npx knex migrate:latest errors out claiming the migrations table already exists—even though I’ve dropped it and can confirm via psql that it’s gone just before running Knex.

Environment

  • OS: Ubuntu (WSL2 on Windows)
  • Node.js: node -v22.12.0
  • PostgreSQL: 16.8 (inside WSL)
  • knex: 3.1.0
  • pg (Node driver): 8.15.6

What happens

  1. Connect via psql to confirm migrations table is gone:

    SELECT EXISTS (  SELECT 1 FROM pg_class  WHERE relname='knex_migrations');-- Returns: f```
  2. Immediately run migrations:

    npx knex migrate:latest --env development```
  3. Knex fails during its internal CREATE TABLE "public"."knex_migrations" step:

    error create table "public"."knex_migrations" ... - relation "knex_migrations" already exists

Knexfile.js(development)

require('dotenv').config();const pg = require('pg');const client = new pg.Client({  host: process.env.DEV_DB_HOST || '172.21.10.102',  port: process.env.DEV_DB_PORT || 5432,  database: process.env.DEV_DB_NAME || 'angushallyapp_dev',  user: process.env.DEV_DB_USER || 'postgres',  password: process.env.DEV_DB_PASSWORD || null});client.connect()  .then(() => {    console.log('KNEXFILE_DEBUG: Connected to DB via direct pg client.');    return client.query('SELECT current_schema()');  })  .then(res => {    console.log('KNEXFILE_DEBUG: current_schema() is:', res.rows[0].current_schema);    return client.query("SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'knex_migrations' AND table_schema = 'public');");  })  .then(res => {    console.log('KNEXFILE_DEBUG: public.knex_migrations exists (direct pg check):', res.rows[0].exists);    return client.end();  })  .then(() => console.log('KNEXFILE_DEBUG: Direct pg client disconnected.'))  .catch(err => {    console.error('KNEXFILE_DEBUG: Error in direct pg client connection or query:', err);    client.end();  });module.exports = {  development: {    client: 'postgresql',    connection: {      host     : process.env.DEV_DB_HOST     || '172.21.10.102',      port     : process.env.DEV_DB_PORT     || 5432,      database : process.env.DEV_DB_NAME     || 'angushallyapp_dev',      user     : process.env.DEV_DB_USER     || 'postgres',      password : process.env.DEV_DB_PASSWORD || null,      searchPath: ['public']    },        pool: {      min: 2,      max: 10    },    migrations: {      directory: './migrations',      tableName: 'public.knex_migrations',      loadExtensions: ['.js']    },    seeds: {      directory: './seeds'    },    debug: true,    log: {      warn(message) {        console.warn('Knex Warning:', message);      },      error(message) {        console.error('Knex Error:', message);      },      deprecate(message) {        console.warn('Knex Deprecation:', message);      },      debug(message) {        console.log('Knex Debug:', message);      }    }  },  production: {    client: 'postgresql',    connection: {      connectionString: process.env.DATABASE_URL,      ssl: {        rejectUnauthorized: false      },      search_path: ['identity', 'habit', 'crm', 'fsa', 'public']    },    pool: {      min: 2,      max: 10    },    migrations: {      directory: './migrations',      tableName: 'public.knex_migrations',      loadExtensions: ['.js']    },    seeds: {      directory: './seeds'    }  }};

Key Debug Output

Knex’s debug logs show that right before attempting its DDL, a direct PG client (using the same creds) confirms the table does not exist. Immediately afterward, the internal CREATE TABLE "public"."knex_migrations" fails with “already exists.”

Things I've tried

  • Confirmed pg_hba.conf allows md5 for angus_dev on all addresses.
  • Set listen_addresses = '*' in postgresql.conf.
  • Specified tableName: 'public.knex_migrations' in the Knex config.
  • Simplified searchPath to ['public'].
  • knex migrate:rollback --all (also errors with the same “already exists”).
  • Restarted Postgres service in WSL.
  • Granted SUPERUSER and DB ownership to angus_dev.

What I don't getWhy is Knex’s internal DDL thinking that public.knex_migrations already exists when a direct check (and psql) confirms it does not? Could this be related to transaction handling, a driver quirk, or something specific about WSL networking/Postgres? Any ideas on what else might be causing this phantom “relation already exists” error?

Thank you to whoever can help.


Viewing all articles
Browse latest Browse all 7074

Trending Articles