remix-run/remix · error · Error

onUpdate() requires references() to be set first

Error message

onUpdate() requires references() to be set first

What it means

ColumnBuilder.onUpdate(action) sets the foreign-key ON UPDATE action and, like onDelete, requires the references() configuration to exist first. Without a reference target there is no foreign key to configure, so the builder throws instead of silently ignoring the call.

Source

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

   * @returns The column builder.
   */
  onDelete(action: ForeignKeyAction): ColumnBuilder<output> {
    if (!this.#definition.references) {
      throw new Error('onDelete() requires references() to be set first')
    }

    this.#definition.references.onDelete = action
    return this
  }

  /**
   * Sets the foreign-key action used when the referenced row is updated.
   * @param action Update action to apply.
   * @returns The column builder.
   */
  onUpdate(action: ForeignKeyAction): ColumnBuilder<output> {
    if (!this.#definition.references) {
      throw new Error('onUpdate() requires references() to be set first')
    }

    this.#definition.references.onUpdate = action
    return this
  }

  /**
   * Adds a check constraint for the column.
   * @param expression SQL check expression.
   * @param name Constraint name.
   * @returns The column builder.
   */
  check(expression: string, name: string): ColumnBuilder<output> {
    let checks = this.#definition.checks ?? []
    checks.push({ expression, name })
    this.#definition.checks = checks
    return this
  }

View on GitHub (pinned to 9696913134)

Solutions

  1. Chain references() first: column.references(() => other.id).onUpdate('cascade').
  2. Remove onUpdate() if the column is not meant to be a foreign key.

Example fix

// before
userId: t.integer('user_id').onUpdate('cascade')

// after
userId: t.integer('user_id').references(() => users.id).onUpdate('cascade')
Defensive patterns

Strategy: validation

Validate before calling

// Always build foreign keys as one chained expression so references() precedes onUpdate()
userId: (t) => t.integer('user_id').references(() => users.id).onUpdate('cascade')

Prevention

When it happens

Trigger: Calling .onUpdate('cascade') on a column builder that has not had .references() called.

Common situations: Schema refactors that lose the references() chain; mirror of the more common onDelete ordering mistake; copy-paste between columns where only some are foreign keys.

Related errors


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