laravel/framework · error · InvalidArgumentException
Illegal operator and value combination.
Error message
Illegal operator and value combination.
What it means
Thrown by prepareValueAndOperator when invalidOperatorAndValue is true: the value is null AND the operator is a known SQL operator that is NOT one of '=', '<=>', '<>', '!='. Laravel only allows null with the null-safe/equality operators; combining null with '>', '<', 'like', 'between', etc. is rejected because it produces semantically wrong SQL. Typically surfaces when a where clause receives an unset request input defaulting to null paired with a comparison operator.
Source
Thrown at src/Illuminate/Database/Query/Builder.php:1068
}, $boolean);
}
/**
* Prepare the value and operator for a where clause.
*
* @param string $value
* @param string $operator
* @param bool $useDefault
* @return array
*
* @throws \InvalidArgumentException
*/
public function prepareValueAndOperator($value, $operator, $useDefault = false)
{
if ($useDefault) {
return [$operator, '='];
} elseif ($this->invalidOperatorAndValue($operator, $value)) {
throw new InvalidArgumentException('Illegal operator and value combination.');
}
return [$value, $operator];
}
/**
* Determine if the given operator and value combination is legal.
*
* Prevents using Null values with invalid operators.
*
* @param string $operator
* @param mixed $value
* @return bool
*/
protected function invalidOperatorAndValue($operator, $value)
{
return is_null($value) && in_array($operator, $this->operators) &&
! in_array($operator, ['=', '<=>', '<>', '!=']);View on GitHub (pinned to bd6b5437e6)
Solutions
- Only apply the where clause when the value is non-null: `$request->filled('min_age') && $q->where('age', '>', $request->min_age)` inside a when() block.
- Use a null-safe operator: `->whereNull('col')` for null checks, or `where('col', '=', null)`.
- Coerce the value with a default: `$request->float('min_age', 0)`.
- Use `when($request->has('x'), fn($q) => $q->where(...))` to skip clauses with missing input.
Example fix
// before
$query->where('price', '>', $request->input('min_price'));
// when min_price is null => Illegal operator and value combination.
// after
$query->when($request->filled('min_price'),
fn ($q) => $q->where('price', '>', $request->input('min_price'))); Defensive patterns
Strategy: validation
Validate before calling
// before building a where clause with a comparison operator
if ($value === null && ! in_array($operator, ['=','<=>','<>','!='], true)) {
// skip the clause or switch to whereNull
return;
} Type guard
function isLegalNullOperator(string $operator): bool
{
return in_array(strtolower($operator), ['=','<=>','<>','!='], true);
} Try / catch
// Prefer validation over try/catch here. If you catch, re-run with a sanitized operator:
try {
$q->where($col, $op, $val);
} catch (\InvalidArgumentException $e) {
if ($val === null) { $q->whereNull($col); }
} Prevention
- Use `when($request->filled('x'), fn($q) => $q->where('x', $op, $request->x))` for optional filters.
- Whitelist comparison operators against user-supplied direction params.
- Validate request inputs with numeric/required rules so null never reaches a comparison clause.
When it happens
Trigger: `->where('age', '>', $request->input('min_age'))` when min_age is absent (null). `->where('name', 'like', $maybeNull)`. Passing `null` as the value to `whereBetween`. Using an operator like '>' against a nullable column without first null-checking the bound value.
Common situations: Optional URL filters where the controller does `$q->where('price', '>=', $request->price)` without filtering nulls; data imports where a source field is empty and coerced to null; conditional where clauses built dynamically without null guards.
Related errors
- The chunkById operation was aborted because the [{$alias}] c
- No record found for the given query.
- $count records were found.
- Property [{$key}] does not exist on the Eloquent builder ins
- Unable to create query for empty collection.
AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06).
Data as JSON: /data/errors/667a433c7256ad1c.json.
Report an issue: GitHub.