{"record":{"id":"8414de1041a83966","repo":"remix-run/remix","slug":"ondelete-requires-references-to-be-set-first","errorCode":null,"errorMessage":"onDelete() requires references() to be set first","messagePattern":"onDelete\\(\\) requires references\\(\\) to be set first","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/data-table/src/lib/column.ts","lineNumber":140,"sourceCode":"\n    this.#definition.references = {\n      table: toTableRef(table),\n      columns: Array.isArray(columns) ? [...columns] : [columns],\n      onDelete: this.#definition.references?.onDelete,\n      onUpdate: this.#definition.references?.onUpdate,\n      name,\n    }\n    return this\n  }\n\n  /**\n   * Sets the foreign-key action used when the referenced row is deleted.\n   * @param action Delete action to apply.\n   * @returns The column builder.\n   */\n  onDelete(action: ForeignKeyAction): ColumnBuilder<output> {\n    if (!this.#definition.references) {\n      throw new Error('onDelete() requires references() to be set first')\n    }\n\n    this.#definition.references.onDelete = action\n    return this\n  }\n\n  /**\n   * Sets the foreign-key action used when the referenced row is updated.\n   * @param action Update action to apply.\n   * @returns The column builder.\n   */\n  onUpdate(action: ForeignKeyAction): ColumnBuilder<output> {\n    if (!this.#definition.references) {\n      throw new Error('onUpdate() requires references() to be set first')\n    }\n\n    this.#definition.references.onUpdate = action\n    return this","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/data-table/src/lib/column.ts#L122-L158","documentation":"ColumnBuilder.onDelete(action) sets the referential action for a foreign key, but it mutates the references() configuration that must already exist on the column. If references() was not called first, there is nothing to attach onDelete to, so the builder throws.","triggerScenarios":"Chaining .onDelete('cascade') on a column builder before calling .references(() => otherTable.id), or splitting the calls and forgetting references().","commonSituations":"Refactoring schema files and dropping the references() line; ordering chained builder calls incorrectly; copy-pasting a column definition that references a table not yet defined so references() was removed.","solutions":["Call references() before onDelete(): column.integer('user_id').references(() => users.id).onDelete('cascade').","If the column is intentionally not a foreign key, remove the onDelete() call."],"exampleFix":"// before\nuserId: t.integer('user_id').onDelete('cascade')\n\n// after\nuserId: t.integer('user_id').references(() => t2.id).onDelete('cascade')","handlingStrategy":"validation","validationCode":"// Always build foreign keys as one chained expression so references() precedes onDelete()\nuserId: (t) => t.integer('user_id').references(() => users.id).onDelete('cascade')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always build foreign-key columns as a single chained expression.","Add a schema smoke test that instantiates every table definition."],"tags":["schema","foreign-keys","column-builder","data-table"],"backgroundTag":"builder-method-order","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}