laravel/framework · error · RuntimeException

The database driver in use does not support spatial indexes.

Error message

The database driver in use does not support spatial indexes.

What it means

SQLite does not support spatial indexes (no R-tree/spatial extension). SQLiteGrammar.compileSpatialIndex() unconditionally throws RuntimeException when a migration requests spatialIndex(). This is a hard driver-capability gate at compile time.

Source

Thrown at src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php:440

            $schema ? $this->wrapValue($schema).'.' : '',
            $this->wrap($command->index),
            $this->wrapTable($table),
            $this->columnize($command->columns)
        );
    }

    /**
     * Compile a spatial index key command.
     *
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
     * @param  \Illuminate\Support\Fluent  $command
     * @return void
     *
     * @throws \RuntimeException
     */
    public function compileSpatialIndex(Blueprint $blueprint, Fluent $command)
    {
        throw new RuntimeException('The database driver in use does not support spatial indexes.');
    }

    /**
     * Compile a foreign key command.
     *
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint
     * @param  \Illuminate\Support\Fluent  $command
     * @return string|null
     */
    public function compileForeign(Blueprint $blueprint, Fluent $command)
    {
        // Handled on table creation or alteration...
    }

    /**
     * Compile a drop table command.
     *
     * @param  \Illuminate\Database\Schema\Blueprint  $blueprint

View on GitHub (pinned to bd6b5437e6)

Solutions

  1. Guard the spatial index with the driver: if (Schema::getConnection()->getDriverName() !== 'sqlite') { $table->spatialIndex('geom'); }
  2. Use Schema::connection('mysql') so the migration runs against the spatial-capable connection only.
  3. For SQLite tests, substitute a normal index on the geometry column or skip the migration via a conditional.

Example fix

// before
Schema::create('places', function (Blueprint $table) {
    $table->id();
    $table->geometry('location');
    $table->spatialIndex('location');
});

// after
Schema::create('places', function (Blueprint $table) {
    $table->id();
    $table->geometry('location');
    if ($table->getConnection()->getDriverName() !== 'sqlite') {
        $table->spatialIndex('location');
    }
});
Defensive patterns

Strategy: validation

Validate before calling

$driver = Schema::getConnection()->getDriverName();
if ($driver !== 'sqlite') {
    $table->spatialIndex('location');
}

Type guard

function supportsSpatialIndex(Blueprint $table): bool
{
    return $table->getConnection()->getDriverName() !== 'sqlite';
}

Prevention

When it happens

Trigger: Calling $table->spatialIndex('geom') or $table->spatialIndex(['col'], 'name') in a migration that executes against a SQLite connection. Common when the test suite uses :memory: SQLite but prod uses MySQL/Postgres with PostGIS.

Common situations: DB_CONNECTION=sqlite in testing while production uses MySQL with spatial data; a shared migrations folder used by both environments; a package that ships spatial indexes without driver guards.

Related errors


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