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

  1. 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.
  2. Use a null-safe operator: `->whereNull('col')` for null checks, or `where('col', '=', null)`.
  3. Coerce the value with a default: `$request->float('min_age', 0)`.
  4. 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

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


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