sequelize/sequelize · error · Error

Upserts are not supported by the ${this.dialect.name} dialec

Error message

Upserts are not supported by the ${this.dialect.name} dialect.

What it means

Thrown at the top of QueryInterface.upsert (query-interface.js:398) when the active dialect reports supports.upserts as false. Sequelize cannot emit a valid ON CONFLICT / MERGE statement for dialects that lack native upsert support, so it aborts before building any SQL rather than producing a silent no-op or incorrect query.

Source

Thrown at packages/core/src/abstract-dialect/query-interface.js:399

  /**
   * Upsert
   *
   * @param {string} tableName    table to upsert on
   * @param {object} insertValues values to be inserted, mapped to field name
   * @param {object} updateValues values to be updated, mapped to field name
   * @param {object} where        where conditions, which can be used for UPDATE part when INSERT fails
   * @param {object} options      query options
   *
   * @returns {Promise<boolean,?number>} Resolves an array with <created, primaryKey>
   */
  // Note: "where" is only used by DB2 and MSSQL. This is because these dialects do not propose any "ON CONFLICT UPDATE" mechanisms
  // The UPSERT pattern in SQL server requires providing a WHERE clause
  // TODO: the user should be able to configure the WHERE clause for upsert instead of the current default which
  //  is using the primary keys.
  async upsert(tableName, insertValues, updateValues, where, options) {
    if (!this.dialect.supports.upserts) {
      throw new Error(`Upserts are not supported by the ${this.dialect.name} dialect.`);
    }

    if (options?.bind) {
      assertNoReservedBind(options.bind);
    }

    options = { ...options };

    const model = options.model;
    const modelDefinition = model.modelDefinition;

    options.type = QueryTypes.UPSERT;
    options.updateOnDuplicate = Object.keys(updateValues);
    options.upsertKeys = options.conflictFields || [];

    if (options.upsertKeys.length === 0) {
      const primaryKeys = Array.from(
        map(

View on GitHub (pinned to 7e1deec499)

Solutions

  1. Check sequelize.dialect.supports.upserts before calling upsert and branch accordingly.
  2. Replace upsert with a manual findOne + (create | update) sequence for unsupported dialects.
  3. Switch to a dialect adapter that supports upserts if the workload requires it.

Example fix

// before
await User.upsert({ id: 1, name: 'Jane' });

// after (guard for dialects without upsert support)
if (sequelize.dialect.supports.upserts) {
  await User.upsert({ id: 1, name: 'Jane' });
} else {
  const [user, created] = await User.findOrCreate({
    where: { id: 1 },
    defaults: { name: 'Jane' },
  });
  if (!created) await user.update({ name: 'Jane' });
}
Defensive patterns

Strategy: type-guard

Validate before calling

function dialectSupportsUpsert(sequelize) {
  return Boolean(sequelize.dialect.supports.upserts);
}

Type guard

function supportsUpserts(sequelize): sequelize is { dialect: { supports: { upserts: true } } } {
  return Boolean((sequelize.dialect.supports as any).upserts);
}

Try / catch

try {
  await Model.upsert(record);
} catch (e) {
  if (/Upserts are not supported/.test(e.message)) {
    // fall back to findOrCreate + update
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling Model.upsert() or queryInterface.upsert() against a dialect whose supports.upserts flag is false; running the same code that worked on Postgres against a dialect with no upsert capability.

Common situations: Switching database dialects during a migration or multi-DB product; using a community/older dialect adapter; deploying code originally written for Postgres/MSSQL to a dialect that lacks ON CONFLICT.

Related errors


AI-assisted analysis of sequelize/sequelize@7e1deec499 (2026-08-03). Data as JSON: /data/errors/84346085e75811ef.json. Report an issue: GitHub.