laravel/framework · error · RuntimeException

This database engine does not support insert or ignore with

Error message

This database engine does not support insert or ignore with returning.

What it means

The base Grammar::compileInsertOrIgnoreReturning() throws because this engine cannot combine INSERT IGNORE semantics with a RETURNING clause. Only SQLite and Postgres override compileInsertOrIgnoreReturning; MySQL and SQL Server do not, so insertOrIgnoreReturning() on those engines reaches this base throw.

Source

Thrown at src/Illuminate/Database/Query/Grammars/Grammar.php:1291

    public function compileInsertOrIgnore(Builder $query, array $values)
    {
        throw new RuntimeException('This database engine does not support inserting while ignoring errors.');
    }

    /**
     * Compile an insert or ignore statement with a returning clause into SQL.
     *
     * @param  \Illuminate\Database\Query\Builder  $query
     * @param  array  $values
     * @param  array  $returning
     * @param  array|null  $uniqueBy
     * @return string
     *
     * @throws \RuntimeException
     */
    public function compileInsertOrIgnoreReturning(Builder $query, array $values, array $returning, ?array $uniqueBy)
    {
        throw new RuntimeException('This database engine does not support insert or ignore with returning.');
    }

    /**
     * Compile an insert and get ID statement into SQL.
     *
     * @param  \Illuminate\Database\Query\Builder  $query
     * @param  array  $values
     * @param  string|null  $sequence
     * @return string
     */
    public function compileInsertGetId(Builder $query, $values, $sequence)
    {
        return $this->compileInsert($query, $values);
    }

    /**
     * Compile an insert statement using a subquery into SQL.
     *

View on GitHub (pinned to bd6b5437e6)

Solutions

  1. On MySQL, call insertOrIgnore() then re-select the matching rows with a subsequent query.
  2. Switch to Postgres or SQLite where the combined operation is supported.
  3. Restrict insertOrIgnoreReturning to pgsql/sqlite via a driver check and provide a two-step fallback elsewhere.

Example fix

// before
$rows = DB::table('imports')->insertOrIgnoreReturning($data, ['id']);

// after (MySQL fallback)
$driver = DB::getDriverName();
if (in_array($driver, ['pgsql','sqlite'])) {
    $rows = DB::table('imports')->insertOrIgnoreReturning($data, ['id']);
} else {
    DB::table('imports')->insertOrIgnore($data);
    $rows = DB::table('imports')->whereIn('hash', $hashes)->get(['id']);
}
Defensive patterns

Strategy: validation

Validate before calling

$driver = DB::getDriverName();
if (in_array($driver, ['pgsql','sqlite'])) {
    $rows = DB::table('imports')->insertOrIgnoreReturning($data, ['id']);
} else {
    throw new \LogicException('insertOrIgnoreReturning requires Postgres/SQLite.');
}

Type guard

function supportsInsertOrIgnoreReturning(\Illuminate\Database\Connection $connection): bool
{
    return $connection instanceof \Illuminate\Database\PostgresConnection
        || $connection instanceof \Illuminate\Database\SQLiteConnection;
}

Prevention

When it happens

Trigger: Calling DB::table(..)->insertOrIgnoreReturning($values, $returning, $uniqueBy) on a mysql or sqlsrv connection.

Common situations: Using insertOrIgnoreReturning to get back inserted rows on Postgres/SQLite, then running the same code against MySQL where INSERT IGNORE exists but RETURNING (without 8.0 RETURNING support wiring) is not implemented by the grammar.

Related errors


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