{"record":{"id":"b995384af7f0ab2e","repo":"yiisoft/yii2","slug":"invalid-operator-operator","errorCode":null,"errorMessage":"Invalid operator '$operator'.","messagePattern":"Invalid operator '\\$operator'\\.","errorType":"exception","errorClass":"yii\\base\\InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"framework/db/conditions/LikeConditionBuilder.php","lineNumber":109,"sourceCode":"     * @return string\n     */\n    private function getEscapeSql()\n    {\n        if ($this->escapeCharacter !== null) {\n            return \" ESCAPE '{$this->escapeCharacter}'\";\n        }\n\n        return '';\n    }\n\n    /**\n     * @param string $operator\n     * @return array\n     */\n    protected function parseOperator($operator)\n    {\n        if (!preg_match('/^(AND |OR |)(((NOT |))I?LIKE)/', $operator, $matches)) {\n            throw new InvalidArgumentException(\"Invalid operator '$operator'.\");\n        }\n        $andor = ' ' . (!empty($matches[1]) ? $matches[1] : 'AND ');\n        $not = !empty($matches[3]);\n        $operator = $matches[2];\n\n        return [$andor, $not, $operator];\n    }\n}\n","sourceCodeStart":91,"sourceCodeEnd":118,"githubUrl":"https://github.com/yiisoft/yii2/blob/66f00d18a29b520f85e8e8f1e32d1e7e7b556cac/framework/db/conditions/LikeConditionBuilder.php#L91-L118","documentation":"yii\\db\\conditions\\LikeConditionBuilder::parseOperator() (framework/db/conditions/LikeConditionBuilder.php:109) decomposes a LikeCondition's operator into conjunction (AND/OR), negation, and LIKE/ILIKE using the regex /^(AND |OR |)(((NOT |))I?LIKE)/. Anything not matching — an optional 'AND '/'OR ' prefix, optional 'NOT ', then exactly 'LIKE' or 'ILIKE' with single spaces — is rejected with InvalidArgumentException. Operators routed through conditionClasses ('LIKE','NOT LIKE','OR LIKE','OR NOT LIKE', pgsql 'ILIKE' variants at framework/db/pgsql/QueryBuilder.php:86-89) always match, so this error comes from LikeCondition objects constructed directly, or from a custom conditionClasses alias whose string does not follow the pattern.","triggerScenarios":"new LikeCondition('name', 'SIMILAR TO', 'foo'); registering a custom alias via setConditionClasses(['MATCH' => LikeCondition::class]) and using ['match','name','x']; hand-built operator strings like 'NOT  LIKE' (double space) or 'like it'.","commonSituations":"Code written before Yii 2.0.14 (when condition building moved to dedicated classes) that built LIKE operators manually; porting PostgreSQL-specific search operators; reusable query helper packages constructing LikeCondition instances.","solutions":["Use only the recognized operators: LIKE, NOT LIKE, OR LIKE, OR NOT LIKE (plus ILIKE variants on PostgreSQL)","For genuinely custom SQL operators use \\yii\\db\\Expression with bound params instead of LikeCondition","If you register an alias in conditionClasses, make its string match the regex exactly (e.g. 'OR NOT ILIKE') or map it to a custom condition class with its own builder"],"exampleFix":"// before\n$cond = new \\yii\\db\\conditions\\LikeCondition('name', 'MATCH', 'foo'); // Invalid operator 'MATCH'\n\n// after\n$cond = new \\yii\\db\\conditions\\LikeCondition('name', 'LIKE', 'foo');\n// or for custom predicates:\n$cond = new \\yii\\db\\Expression('name ~ :pat', [':pat' => '^foo']);","handlingStrategy":"validation","validationCode":"function isValidLikeOperator(string $operator): bool\n{\n    return (bool) preg_match('/^(AND |OR |)(((NOT |))I?LIKE)/', $operator);\n}\n\nif (!isValidLikeOperator($op)) {\n    throw new \\InvalidArgumentException(\"Unsupported LIKE operator: $op\");\n}\n$cond = new \\yii\\db\\conditions\\LikeCondition($column, $op, $value);","typeGuard":null,"tryCatchPattern":"try {\n    $sql = $queryBuilder->buildExpression($condition, $params);\n} catch (\\yii\\base\\InvalidArgumentException $e) {\n    // operator rejected by parseOperator — fall back to a raw Expression\n    $sql = $queryBuilder->buildExpression(new \\yii\\db\\Expression($rawSql, $params), $params);\n}","preventionTips":["Whitelist operators instead of building them from strings: in_array($op, ['LIKE','NOT LIKE','OR LIKE','OR NOT ILIKE'], true)","Use the array format ['like', $col, $val] — it routes through conditionClasses and cannot hit parseOperator with garbage","For custom predicates implement a dedicated condition class + builder instead of reusing LikeCondition"],"tags":["yii2","database","query-builder","like","operator","regex-validation"],"backgroundTag":"invalid-query-operator","analyzedSha":"66f00d18a29b520f85e8e8f1e32d1e7e7b556cac","analyzedAt":"2026-08-17T05:17:23.470Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}