laravel/framework · error · RuntimeException

This database driver does not support modifying columns.

Error message

This database driver does not support modifying columns.

What it means

Grammar::compileChange() throws RuntimeException on the base; all four shipped grammars override it. It compiles the SQL for a column-modify command ($table->...->change()). Reaching the base means the active grammar is the unimplemented base class - i.e. a custom driver that cannot emit ALTER TABLE ... MODIFY statements.

Solutions

  1. Run modify-column migrations on sqlite/mysql/pgsql/sqlsrv.
  2. Implement compileChange() in your custom grammar (it must return one or more ALTER statements appropriate to the engine).
  3. Rewrite the migration to drop and recreate the column instead of using ->change() where the engine allows.

Example fix

// before - throws on a custom driver that lacks compileChange
Schema::table('users', function (Blueprint $t) {
    $t->string('email', 320)->change();
});

// after - raw ALTER for the unsupported engine
DB::connection('custom')->statement('ALTER TABLE users MODIFY email VARCHAR(320)');
Defensive patterns

Strategy: type-guard

Validate before calling

$grammar = Schema::getConnection()->getSchemaGrammar();
if (get_class($grammar) === \Illuminate\Database\Schema\Grammars\Grammar::class) {
    throw new \DomainException('Connection uses the base Grammar; ->change() is unsupported.');
}

Type guard

function supportsCompileChange(\Illuminate\Database\Schema\Grammars\Grammar $grammar): bool
{
    return (new \ReflectionMethod($grammar, 'compileChange'))
        ->getDeclaringClass()->getName() !== \Illuminate\Database\Schema\Grammars\Grammar::class;
}

Try / catch

try {
    Schema::table('users', fn ($t) => $t->string('email', 320)->change());
} catch (\RuntimeException $e) {
    if (str_contains($e->getMessage(), 'modifying columns')) {
        DB::statement('ALTER TABLE users MODIFY email VARCHAR(320)');
    } else {
        throw $e;
    }
}

Prevention

When it happens

Trigger: Issuing $table->integer('foo')->change() (or any ->change() call) in a migration on a connection whose SchemaGrammar is the base Grammar. The Blueprint builds a change command, dispatches it to the grammar, and the base refuses.

Common situations: A custom driver whose grammar was scaffolded but compileChange was never written; a test that injects the base Grammar; running migrations against an experimental engine.

Related errors


AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11). Data as JSON: /api/errors/4a25b402ed274bd4. Report an issue: GitHub.

Appendix: source

Thrown at src/Illuminate/Database/Schema/Grammars/Grammar.php:212

        return sprintf('alter table %s rename column %s to %s',
            $this->wrapTable($blueprint),
            $this->wrap($command->from),
            $this->wrap($command->to)
        );
    }

    /**
     * Compile a change column command into a series of SQL statements.
     *
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
     * @param  \Illuminate\Support\Fluent  $command
     * @return list<string>|string
     *
     * @throws \RuntimeException
     */
    public function compileChange(Blueprint $blueprint, Fluent $command)
    {
        throw new RuntimeException('This database driver does not support modifying columns.');
    }

    /**
     * Compile a fulltext index key command.
     *
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
     * @param  \Illuminate\Support\Fluent  $command
     * @return string
     *
     * @throws \RuntimeException
     */
    public function compileFulltext(Blueprint $blueprint, Fluent $command)
    {
        throw new RuntimeException('This database driver does not support fulltext index creation.');
    }

    /**
     * Compile a drop fulltext index command.

View on GitHub (pinned to e0f6eb3518)