remix-run/remix · error · Error

Invalid column "{columnName}" for table "{tableName}". Expec

Error message

Invalid column "{columnName}" for table "{tableName}". Expected a column(...) builder

What it means

This error is thrown by resolveTableColumns when a table's column definition object contains a value that is not a ColumnBuilder instance. Every entry in the columns object passed to defineTable/createTable must be created with the column(...) builder so the library can read its type, options, and defaults.

Source

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

    }),
  }) as ColumnReference<tableName, columnName>
}

function resolveTableColumns<columns extends TableColumnsDefinition>(
  tableName: string,
  columns: columns,
): { [column in keyof columns & string]: ColumnDefinition } {
  let columnDefinitions: Record<string, ColumnDefinition> = {}

  for (let columnName in columns) {
    if (!Object.prototype.hasOwnProperty.call(columns, columnName)) {
      continue
    }

    let column = columns[columnName]

    if (!(column instanceof ColumnBuilder)) {
      throw new Error(
        'Invalid column "' +
          columnName +
          '" for table "' +
          tableName +
          '". Expected a column(...) builder',
      )
    }

    columnDefinitions[columnName] = column.build()
  }

  return Object.freeze(columnDefinitions) as {
    [column in keyof columns & string]: ColumnDefinition
  }
}

/**
 * Defines a one-to-many relation from `source` to `target`.

View on GitHub (pinned to 9696913134)

Solutions

  1. Ensure every columns entry is created with the library's column(...) builder
  2. Check for typos like passing column types (e.g. 'string') instead of column.string()
  3. Remove any spread of non-builder objects from the columns definition

Example fix

// before
const posts = createTable('posts', {
  title: 'string',
})
// after
import { column, createTable } from '...'
const posts = createTable('posts', {
  title: column.string(),
})
Defensive patterns

Strategy: validation

Validate before calling

for (const [name, def] of Object.entries(columns)) {
  if (!(def instanceof ColumnBuilder)) throw new TypeError(`column ${name} is not a builder`)
}

Type guard

const isColumnBuilder = (v: unknown): v is ColumnBuilder => v instanceof ColumnBuilder

Prevention

When it happens

Trigger: Passing a plain value, class instance, or imported non-builder (e.g. columns: { id: 1 } or { createdAt: SomeORM.column }) inside the table's columns definition; also wrapping columns in an extra layer or passing a serialized/parsed definition.

Common situations: Copy-pasting schema code from another ORM, forgetting to call column(), spreading plain objects into the columns definition, or a refactor that renamed the column import.

Related errors


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