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

  1. Provide all three operands: ['between', 'column', $min, $max]
  2. When bounds are optional, only add the condition when both are non-null; otherwise fall back to ['>','col',$min] / ['<','col',$max]
  3. 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

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


AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17). Data as JSON: /api/errors/fd17c20c56ff3ab1. Report an issue: GitHub.