laravel/framework · error · RuntimeException
This database engine does not support JSON operations.
Error message
This database engine does not support JSON operations.
What it means
The base Grammar class's wrapJsonSelector() throws because the database engine in use does not override it to support JSON path selectors. Whenever the query builder encounters a column containing '->' (a JSON path), it calls wrapJsonSelector; on a driver without JSON support (the base Grammar, or one that did not override) it refuses rather than emit broken SQL.
Solutions
- Switch the connection to a driver that supports JSON (mysql with json_get, pgsql with ->/->>).
- Avoid '->' selectors for this connection - cast/store the field as a regular column or use a manual whereRaw with the engine's JSON function.
- If you wrote a custom Grammar, override wrapJsonSelector (and wrapJsonFieldAndPath) to emit correct SQL.
- Check config/database.php that the connection maps to the intended driver.
Example fix
// before - throws on a driver without JSON support
$users = User::where('preferences->theme', 'dark')->get();
// after - use the engine's native function via whereRaw (sqlsrv example)
$users = User::whereRaw("JSON_VALUE(preferences, '$.theme') = ?", ['dark'])->get();
// or migrate the column to a real table column / use a supported driver Defensive patterns
Strategy: validation
Validate before calling
// Detect JSON-selector usage on a driver that does not override wrapJsonSelector
$grammar = \DB::connection()->getQueryGrammar();
if (str_contains($column, '->') && (new \ReflectionMethod($grammar, 'wrapJsonSelector'))->getDeclaringClass()->getName() === \Illuminate\Database\Grammar::class) {
throw new \RuntimeException('Current DB driver does not support JSON selectors; use whereRaw().');
} Type guard
function driverSupportsJson(\Illuminate\Database\Connection $connection): bool {
$r = new \ReflectionMethod($connection->getQueryGrammar(), 'wrapJsonSelector');
return $r->getDeclaringClass()->getName() !== \Illuminate\Database\Grammar::class;
} Try / catch
try {
$users = User::where('meta->theme', 'dark')->get();
} catch (\RuntimeException $e) {
if (str_contains($e->getMessage(), 'does not support JSON operations')) {
// rewrite using the engine's native function
$users = User::whereRaw("JSON_VALUE(meta, '$.theme') = ?", ['dark'])->get();
} else { throw $e; }
} Prevention
- Confirm config/database.php maps the connection to a JSON-capable driver (mysql/pgsql).
- Avoid '->' selectors for connections that may resolve to the base Grammar.
- If you wrote a custom Grammar, override wrapJsonSelector and wrapJsonFieldAndPath.
- Use whereRaw with the engine's JSON function as a portable fallback.
When it happens
Trigger: Using a '->' JSON selector (e.g. where('meta->theme', 'dark') or ->select('users->name')) against a connection whose schema grammar extends the base Grammar (no JSON support). Common with the base/abstract grammar, some sqlsrv configurations, or a misconfigured custom connection.
Common situations: Developing with JSON columns on MySQL/PostgreSQL then running tests on a driver that lacks override; a custom DB driver/connection that forgot to override wrapJsonSelector; SQLite < 3.9 / older setups; using -> on a connection that resolves to the base Grammar.
Related errors
- This database engine does not support JSON contains…
- This database engine does not support JSON contains key…
- This database engine does not support JSON length…
- This database engine does not support JSON overlaps…
- A driver must be specified.
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/9712b4b9d0dc3394.
Report an issue: GitHub.
Appendix: source
Thrown at src/Illuminate/Database/Grammar.php:177
{
if ($value !== '*') {
return '"'.str_replace('"', '""', $value).'"';
}
return $value;
}
/**
* Wrap the given JSON selector.
*
* @param string $value
* @return string
*
* @throws \RuntimeException
*/
protected function wrapJsonSelector($value)
{
throw new RuntimeException('This database engine does not support JSON operations.');
}
/**
* Determine if the given string is a JSON selector.
*
* @param string $value
* @return bool
*/
protected function isJsonSelector($value)
{
return str_contains($value, '->');
}
/**
* Convert an array of column names into a delimited string.
*
* @param array<\Illuminate\Contracts\Database\Query\Expression|string> $columns
* @return stringView on GitHub (pinned to e0f6eb3518)