laravel/framework · error · RuntimeException

This database engine does not support JSON overlaps…

Error message

This database engine does not support JSON overlaps operations.

What it means

The base Grammar's compileJsonOverlaps throws by default. Only MySqlGrammar overrides it (using JSON_OVERLAPS, available in MySQL 8.0.17+ and MariaDB 10.9+). PostgreSQL, SQLite, and SQL Server grammars do not override it, so whereJsonOverlaps on those connections triggers the throw. JSON overlap checks whether two JSON arrays share at least one element.

Solutions

  1. Switch to a MySQL 8.0.17+ or MariaDB 10.9+ connection — the only grammars that override compileJsonOverlaps
  2. On PostgreSQL, rewrite as ->whereJsonContains('tags', 'php')->orWhereJsonContains('tags', 'laravel') (PostgreSQL supports JSON contains via jsonb @>)
  3. On SQLite/SQL Server, use a raw WHERE with EXISTS + json_each (SQLite) or OPENJSON (SQL Server)
  4. Use a separate junction/relationship table instead of JSON arrays for overlapping tag queries

Example fix

// before — fails on PostgreSQL / SQLite / SQL Server
Product::whereJsonOverlaps('tags', ['php', 'laravel'])->get();

// after — works on PostgreSQL (which supports jsonb contains)
Product::where(function ($q) {
    $q->whereJsonContains('tags', 'php')->orWhereJsonContains('tags', 'laravel');
})->get();
Defensive patterns

Strategy: type-guard

Validate before calling

$driver = DB::connection()->getDriverName();

if ($driver === 'mysql') {
    $query->whereJsonOverlaps('tags', ['php', 'laravel']);
} else {
    // fallback: chain whereJsonContains for each value
    $query->where(function ($q) use ($tags) {
        foreach ($tags as $tag) {
            $q->orWhereJsonContains('tags', $tag);
        }
    });
}

Type guard

function supportsJsonOverlaps(): bool {
    return DB::connection()->getDriverName() === 'mysql';
}

Try / catch

try {
    $query->whereJsonOverlaps('tags', ['php', 'laravel']);
} catch (\RuntimeException $e) {
    if (str_contains($e->getMessage(), 'JSON overlaps')) {
        $query->where(function ($q) {
            $q->whereJsonContains('tags', 'php')->orWhereJsonContains('tags', 'laravel');
        });
    } else {
        throw $e;
    }
}

Prevention

When it happens

Trigger: Calling ->whereJsonOverlaps('tags', ['php', 'laravel']) or ->orWhereJsonOverlaps on a PostgreSQL, SQLite, or SQL Server connection.

Common situations: Developer assumes JSON_OVERLAPS is a standard SQL function. Code written for MySQL/MariaDB then deployed against PostgreSQL. Test suite running on SQLite while production uses MySQL.

Related errors


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

Appendix: source

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

        return $not.$this->compileJsonOverlaps(
            $where['column'],
            $this->parameter($where['value'])
        );
    }

    /**
     * Compile a "JSON overlaps" statement into SQL.
     *
     * @param  string  $column
     * @param  string  $value
     * @return string
     *
     * @throws \RuntimeException
     */
    protected function compileJsonOverlaps($column, $value)
    {
        throw new RuntimeException('This database engine does not support JSON overlaps operations.');
    }

    /**
     * Prepare the binding for a "JSON contains" statement.
     *
     * @param  mixed  $binding
     * @return string
     */
    public function prepareBindingForJsonContains($binding)
    {
        return json_encode($binding, JSON_UNESCAPED_UNICODE);
    }

    /**
     * Compile a "where JSON contains key" clause.
     *
     * @param  \Illuminate\Database\Query\Builder  $query
     * @param  array  $where

View on GitHub (pinned to e0f6eb3518)