remix-run/remix · error · Error

Table "{tableName}" must include an "id" column or an explic

Error message

Table "{tableName}" must include an "id" column or an explicit primaryKey

What it means

Every table needs a primary key for row identity and relations. If you do not pass an explicit primaryKey option, the library defaults to an 'id' column, and this error fires when the columns definition has neither an 'id' column nor an explicit primaryKey.

Source

Thrown at packages/data-table/src/lib/table.ts:1093

  if (typeof value === 'string') {
    return JSON.stringify(value)
  }

  if (value instanceof Date) {
    return 'date:' + value.toISOString()
  }

  return JSON.stringify(value)
}

function normalizePrimaryKey(
  tableName: string,
  columns: TableColumnsDefinition,
  primaryKey?: string | readonly string[],
): string[] {
  if (primaryKey === undefined) {
    if (!Object.prototype.hasOwnProperty.call(columns, 'id')) {
      throw new Error(
        'Table "' + tableName + '" must include an "id" column or an explicit primaryKey',
      )
    }

    return ['id']
  }

  let keys = Array.isArray(primaryKey) ? [...primaryKey] : [primaryKey]

  if (keys.length === 0) {
    throw new Error('Table "' + tableName + '" primaryKey must contain at least one column')
  }

  for (let key of keys) {
    if (!Object.prototype.hasOwnProperty.call(columns, key)) {
      throw new Error('Table "' + tableName + '" primaryKey column "' + key + '" does not exist')
    }
  }

View on GitHub (pinned to 9696913134)

Solutions

  1. Add an id: column.id() (or equivalent) column to the definition
  2. Or pass primaryKey: 'yourKeyColumn' / primaryKey: ['a','b'] to createTable
  3. If the table truly has no key, reconsider — relations and lookups require one

Example fix

// before
const users = createTable('users', {
  email: column.string(),
})
// after
const users = createTable('users', {
  userId: column.uuid(),
  email: column.string(),
}, { primaryKey: 'userId' })
Defensive patterns

Strategy: validation

Validate before calling

if (!('id' in columns) && !options?.primaryKey) throw new Error('table needs id or primaryKey')

Prevention

When it happens

Trigger: createTable('users', { email: column.string() }) with no primaryKey option, or renaming the id column (e.g. userId) without adding primaryKey: 'userId'.

Common situations: Legacy tables with non-id keys, generated schemas that omit id, or accidental deletion of the id column during a refactor.

Related errors


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