yiisoft/yii2 · error · yii\base\InvalidArgumentException
Operator '$operator' requires three operands.
Error message
Operator '$operator' requires three operands.
What it means
Thrown by yii\db\conditions\BetweenCondition::fromArrayDefinition() (framework/db/conditions/BetweenCondition.php:95) when a BETWEEN/NOT BETWEEN condition in operator-array format does not have all three operands (column, min, max) set. QueryBuilder::createConditionFromArray() (framework/db/QueryBuilder.php:1600-1610) routes every ['between', ...] / ['not between', ...] where() array here, so the error surfaces when the SQL is built (e.g. at ->all() or ->createCommand()), not when where() is called. Because the guard uses isset(), a null operand (e.g. a null $max bound) fails exactly like a missing one.
Source
Thrown at framework/db/conditions/BetweenCondition.php:95
return $this->intervalStart;
}
/**
* @return mixed
*/
public function getIntervalEnd()
{
return $this->intervalEnd;
}
/**
* {@inheritdoc}
* @throws InvalidArgumentException if wrong number of operands have been given.
*/
public static function fromArrayDefinition($operator, $operands)
{
if (!isset($operands[0], $operands[1], $operands[2])) {
throw new InvalidArgumentException("Operator '$operator' requires three operands.");
}
return new static($operands[0], $operator, $operands[1], $operands[2]);
}
}
View on GitHub (pinned to 66f00d18a2)
Solutions
- Provide all three operands: ['between', 'column', $min, $max]
- When bounds are optional, only add the condition when both are non-null; otherwise fall back to ['>','col',$min] / ['<','col',$max]
- When assembling conditions dynamically, verify operand count before appending the operator element
Example fix
// before
$items = (new Query())->from('product')
->where(['between', 'price', $min, $max]) // throws when $min or $max is null (isset)
->all();
// after
$query = (new Query())->from('product');
if ($min !== null && $max !== null) {
$query->andWhere(['between', 'price', $min, $max]);
} else {
if ($min !== null) { $query->andWhere(['>', 'price', $min]); }
if ($max !== null) { $query->andWhere(['<', 'price', $max]); }
}
$items = $query->all(); Defensive patterns
Strategy: validation
Validate before calling
function hasBetweenOperands(array $condition): bool
{
// operator at 0, then column, min, max — all set and non-null
return isset($condition[1], $condition[2], $condition[3])
&& $condition[2] !== null
&& $condition[3] !== null;
}
// usage
if (hasBetweenOperands($where)) {
$query->andWhere($where);
} Try / catch
try {
$rows = $query->createCommand()->queryAll(); // condition is compiled here
} catch (\yii\base\InvalidArgumentException $e) {
\Yii::warning('Malformed BETWEEN condition: ' . $e->getMessage(), __METHOD__);
$rows = [];
} Prevention
- Normalize filter input before building where() arrays: empty request values become null — skip the condition instead of passing it
- Remember isset() treats null as missing; a null bound fails the guard exactly like an absent one
- Unit-test every dynamic filter with the 'all bounds empty' case
When it happens
Trigger: Calling ->where(['between','price',10]) or ->andWhere(['not between','created_at',$from,$to]) with a missing bound; building range filters from user input where one bound is absent or null; passing ['between','col',null,10] — isset() treats the null slot as unset.
Common situations: Search/filter forms with optional min/max fields where empty input becomes null; refactoring a raw SQL BETWEEN into array format and forgetting one operand; note that andFilterWhere() is safe here — filterCondition (framework/db/QueryTrait.php:270-276) drops the whole BETWEEN condition when either bound is empty.
Related errors
- Operator '$operator' requires two operands.
- Operator '$operator' requires two operands.
- Operator '$operator' requires exactly one operand.
- Operator '$operator' requires two operands.
- Subquery for EXISTS operator must be a Query object.
AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17).
Data as JSON: /api/errors/fd17c20c56ff3ab1.
Report an issue: GitHub.