remix-run/remix · error · Error

Unsupported operation kind

Error message

Unsupported operation kind

What it means

compileMysqlOperation is the exhaustive tail of a switch over operation.kind for the MySQL SQL compiler: it handles known kinds (insert, update, delete, upsert, etc.) and throws 'Unsupported operation kind' for anything else. Seeing it means an operation object reached the compiler with a kind the MySQL backend does not implement — usually a new/typo kind or a cross-backend operation object.

Source

Thrown at packages/data-table-mysql/src/lib/sql-compiler.ts:113

      values: context.values,
    }
  }

  if (operation.kind === 'delete') {
    return {
      text:
        'delete from ' +
        quotePath(getTableName(operation.table)) +
        compileWhereClause(operation.where, context),
      values: context.values,
    }
  }

  if (operation.kind === 'upsert') {
    return compileUpsertOperation(operation, context)
  }

  throw new Error('Unsupported operation kind')
}

function compileInsertOperation(
  table: OperationTable,
  values: Record<string, unknown>,
  context: CompileContext,
): SqlStatement {
  let columns = Object.keys(values)

  if (columns.length === 0) {
    return {
      text: 'insert into ' + quotePath(getTableName(table)) + ' () values ()',
      values: context.values,
    }
  }

  return {
    text:

View on GitHub (pinned to 9696913134)

Solutions

  1. Use the official operation builder functions for the MySQL driver instead of hand-built objects
  2. Align versions of the data-table core package and the MySQL backend package
  3. Check the operation.kind against the MySQL compiler's supported kinds before compiling

Example fix

// before
const op = { kind: 'merge', table: 'users', values } // unsupported kind
await driver.execute(compile(op))
// after
const op = upsertOp('users', values, { update: values })
await driver.execute(compile(op))
Defensive patterns

Strategy: type-guard

Validate before calling

const supported = new Set(['insert', 'update', 'delete', 'upsert'])
if (!supported.has(op.kind)) throw new Error(`unsupported kind ${op.kind} for MySQL`)

Type guard

type MysqlOperationKind = 'insert' | 'update' | 'delete' | 'upsert'
function isMysqlOperation(op: { kind: string }): op is { kind: MysqlOperationKind } {
  return ['insert', 'update', 'delete', 'upsert'].includes(op.kind)
}

Try / catch

try { const sql = compileMysqlOperation(op, ctx) } catch (e) { if (e instanceof Error && e.message === 'Unsupported operation kind') { /* rebuild op with supported builder */ } throw e }

Prevention

When it happens

Trigger: Passing a hand-constructed operation like { kind: 'merge', ... } or { kind: 'bulkInsert' } to driver compile/execute APIs; mixing operation builders from a different data-table backend (postgres) with the MySQL driver; typos in kind strings.

Common situations: Version mismatch where a newer @remix-run/data-table core emits a kind the installed MySQL compiler doesn't know; custom operation construction instead of using builder APIs; copying operation examples from another backend's docs.

Related errors


AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27). Data as JSON: /api/errors/1cde3929808213ee. Report an issue: GitHub.