{"record":{"id":"ea1f6f2d215a5e72","repo":"yiisoft/yii2","slug":"operator-operator-requires-two-operands-ea1f6f","errorCode":null,"errorMessage":"Operator '$operator' requires two operands.","messagePattern":"Operator '\\$operator' requires two operands\\.","errorType":"exception","errorClass":"yii\\base\\InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"framework/db/conditions/SimpleCondition.php","lineNumber":81,"sourceCode":"        return $this->column;\n    }\n\n    /**\n     * @return mixed\n     */\n    public function getValue()\n    {\n        return $this->value;\n    }\n\n    /**\n     * {@inheritdoc}\n     * @throws InvalidArgumentException if wrong number of operands have been given.\n     */\n    public static function fromArrayDefinition($operator, $operands)\n    {\n        if (count($operands) !== 2) {\n            throw new InvalidArgumentException(\"Operator '$operator' requires two operands.\");\n        }\n\n        return new static($operands[0], $operator, $operands[1]);\n    }\n}\n","sourceCodeStart":63,"sourceCodeEnd":87,"githubUrl":"https://github.com/yiisoft/yii2/blob/66f00d18a29b520f85e8e8f1e32d1e7e7b556cac/framework/db/conditions/SimpleCondition.php#L63-L87","documentation":"yii\\db\\conditions\\SimpleCondition::fromArrayDefinition() (framework/db/conditions/SimpleCondition.php:81) handles binary operators (=, !=, <>, >, <, >=, <=) in operator format and requires count($operands) === 2 — column and value, no more, no less. SimpleCondition is also the fallback for ANY operator string not present in QueryBuilder::$conditionClasses (framework/db/QueryBuilder.php:1604-1607), so unknown operators with a wrong operand count surface here too. Because it uses count() rather than isset(), a null value is accepted — ['=','col',null] passes this check and later builds broken SQL, so NULL comparisons must use the dedicated is/is not operators.","triggerScenarios":"->where(['>','age']) missing the value; ['='] alone; ['<=','price',10,'extra'] with a stray third element; an operator typo like '==' still routes here (unknown operator + 2 operands builds invalid SQL that fails at the DB instead).","commonSituations":"Dynamic filters where the value variable is unset or the filter row was partially built; concatenating condition arrays with off-by-one pushes; mixing hash and operator formats in one array.","solutions":["Supply exactly two operands: ['>', 'age', 18]","For NULL comparisons use the dedicated operators: ['is', 'col', null] / ['is not', 'col', null] instead of ['=', 'col', null]","Build operator conditions in one step — [$op, $column, $value] — rather than pushing pieces separately"],"exampleFix":"// before\n$query->where(['=', 'deleted_at', null]); // passes count check but yields 'deleted_at = NULL' (never true)\n\n// after\n$query->where(['is', 'deleted_at', null]);","handlingStrategy":"validation","validationCode":"function isValidSimpleCondition(array $condition): bool\n{\n    return isset($condition[0], $condition[1]) && count($condition) === 3;\n}\n\nif (isValidSimpleCondition([$op, $column, $value])) {\n    $query->andWhere([$op, $column, $value]);\n}","typeGuard":null,"tryCatchPattern":"try {\n    $rows = $query->all();\n} catch (\\yii\\base\\InvalidArgumentException $e) {\n    \\Yii::warning('Malformed operator condition: ' . $e->getMessage(), __METHOD__);\n    $rows = [];\n}","preventionTips":["Build operator conditions atomically as [$op, $column, $value] — never push pieces into an existing condition array","Any unknown operator routes to SimpleCondition, so typo'd operators fail here or at the DB — whitelist allowed operators","Use ['is'/'is not', $col, null] for NULL comparisons; ['=', $col, null] passes validation but produces SQL that never matches"],"tags":["yii2","database","query-builder","operator","where-condition","validation"],"backgroundTag":"malformed-query-condition","analyzedSha":"66f00d18a29b520f85e8e8f1e32d1e7e7b556cac","analyzedAt":"2026-08-17T05:17:23.470Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}