laravel/framework · error · InvalidArgumentException

There is no column with name '$column' on table '$table'.

Error message

There is no column with name '$column' on table '$table'.

What it means

Thrown by Builder::getColumnType() when it iterates the table's columns (via getColumns()) and finds no row whose name matches the requested $column (case-insensitive). It is an InvalidArgumentException because the caller asked for the type of a column the schema manager cannot see. This usually means the column does not exist, was renamed/dropped in a migration that has not run, or the table prefix/schema is wrong.

Source

Thrown at src/Illuminate/Database/Schema/Builder.php:373

     *
     * @param  string  $table
     * @param  string  $column
     * @param  bool  $fullDefinition
     * @return string
     *
     * @throws \InvalidArgumentException
     */
    public function getColumnType($table, $column, $fullDefinition = false)
    {
        $columns = $this->getColumns($table);

        foreach ($columns as $value) {
            if (strtolower($value['name']) === strtolower($column)) {
                return $fullDefinition ? $value['type'] : $value['type_name'];
            }
        }

        throw new InvalidArgumentException("There is no column with name '$column' on table '$table'.");
    }

    /**
     * Get the column listing for a given table.
     *
     * @param  string  $table
     * @return list<string>
     */
    public function getColumnListing($table)
    {
        return array_column($this->getColumns($table), 'name');
    }

    /**
     * Get the columns for a given table.
     *
     * @param  string  $table
     * @return list<array{name: string, type: string, type_name: string, collation: string|null, nullable: bool, default: mixed, auto_increment: bool, comment: string|null, generation: array{type: string, expression: string|null}|null}>

View on GitHub (pinned to bd6b5437e6)

Solutions

  1. Verify the column actually exists: run Schema::getColumnListing($table) and check the name is present (case-insensitive).
  2. Run php artisan migrate on the environment to apply pending migrations that create/rename the column.
  3. Confirm config('database.connections.*.prefix') matches the table prefix actually used; Builder prepends getTablePrefix() at Builder.php:397.
  4. If using a schema-qualified table name, pass only 'schema.table' (two parts); three parts throws error 225.
  5. Check for casing drift: comparison is strtolower-based (Builder.php:368) so exact case is not required, but trailing spaces or hidden characters will fail.

Example fix

// before
$type = Schema::getColumnType('users', 'email_address');

// after
$columns = array_map('strtolower', Schema::getColumnListing('users'));
if (in_array(strtolower('email_address'), $columns, true)) {
    $type = Schema::getColumnType('users', 'email_address');
} else {
    // column missing — run migrations or fix the name
}
Defensive patterns

Strategy: validation

Validate before calling

$columns = array_map('strtolower', Schema::getColumnListing($table));
if (! in_array(strtolower($column), $columns, true)) {
    throw new \InvalidArgumentException("Missing column {$column} on {$table}");
}
$type = Schema::getColumnType($table, $column);

Type guard

function columnExists(string $table, string $column): bool
{
    $listing = array_map('strtolower', (array) Schema::getColumnListing($table));

    return in_array(strtolower($column), $listing, true);
}

Try / catch

try {
    $type = Schema::getColumnType($table, $column);
} catch (\InvalidArgumentException $e) {
    // log and degrade — column is absent, do not assume a type
    $type = null;
}

Prevention

When it happens

Trigger: Calling Schema::getColumnType($table, $column) or any API that delegates to it (e.g. Doctrine-style type detection, $table->change() in a migration that reads the existing type) where $column is not present among the rows returned by compileColumns/processColumns for that table. Also triggered by passing a fully-qualified name with the wrong schema/prefix so getColumns() resolves a different table.

Common situations: Migration not yet run on the current environment (column exists in code but not in DB); column was renamed but old name still referenced; table prefix mismatch between config and actual table; typos in column name in a $table->change() migration; SQLite/old MySQL where the information_schema query returns unexpected casing.

Related errors


AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06). Data as JSON: /data/errors/f7c27e58c0558b78.json. Report an issue: GitHub.