{"record":{"id":"7d263d17ccf4d0ff","repo":"yiisoft/yii2","slug":"key-is-not-a-column-name-and-can-not-be-used","errorCode":null,"errorMessage":"Key \"{}\" is not a column name and can not be used as a filter","messagePattern":"Key \"(.+?)\" is not a column name and can not be used as a filter","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"framework/db/ActiveRecord.php","lineNumber":238,"sourceCode":"     * This method will ensure that an array condition only filters on existing table columns.\n     *\n     * @param array $condition condition to filter.\n     * @param array $aliases\n     * @return array filtered condition.\n     * @throws InvalidArgumentException in case array contains unsafe values.\n     * @throws InvalidConfigException\n     * @since 2.0.15\n     * @internal\n     */\n    protected static function filterCondition(array $condition, array $aliases = [])\n    {\n        $result = [];\n        $db = static::getDb();\n        $columnNames = static::filterValidColumnNames($db, $aliases);\n\n        foreach ($condition as $key => $value) {\n            if (is_string($key) && !in_array($db->quoteSql($key), $columnNames, true)) {\n                throw new InvalidArgumentException('Key \"' . $key . '\" is not a column name and can not be used as a filter');\n            }\n            $result[$key] = is_array($value) ? array_values($value) : $value;\n        }\n\n        return $result;\n    }\n\n    /**\n     * Valid column names are table column names or column names prefixed with table name or table alias\n     *\n     * @param Connection $db\n     * @param array $aliases\n     * @return array\n     * @throws InvalidConfigException\n     * @since 2.0.17\n     * @internal\n     */\n    protected static function filterValidColumnNames($db, array $aliases)","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/yiisoft/yii2/blob/66f00d18a29b520f85e8e8f1e32d1e7e7b556cac/framework/db/ActiveRecord.php#L220-L256","documentation":"findByCondition() routes associative-array conditions through filterCondition(), where every string key must be a valid column: a column of the AR table, or a column prefixed with the table name or with one of the query's declared table aliases (filterValidAliases). Any other string key raises InvalidArgumentException, preventing untrusted input from injecting arbitrary SQL fragments through find conditions.","triggerScenarios":"Model::findOne(['usrname' => 'bob']) with a typo; Model::findAll(array_filter($_GET)) letting arbitrary request keys reach the query; keys like 'COUNT(*)' or 'o.status' where 'o' is not an alias present in the query's joins.","commonSituations":"Passing request data straight into findOne()/findAll(); filtering on a joined table's column while forgetting the alias must appear in the query's join/joinWith; refactors that rename columns; using operator keys like 'like' as hash keys instead of list conditions.","solutions":["Whitelist condition keys against the table schema before calling find: array_intersect_key($condition, array_flip($model::getTableSchema()->getColumnNames()))","Fix the column-name typo so it matches a real column","For joined tables, prefix with the table name or a declared alias: ['{{%order}}.status' => 2]","For anything that is not a plain column, use find()->andWhere() with operator format (['=', 'expr', $value]) instead of findOne/findAll"],"exampleFix":"// before\n$customers = Customer::findAll($_GET['Customer']); // attacker-controlled keys throw or probe\n\n// after\n$schema = Customer::getTableSchema();\n$filters = array_intersect_key($_GET['Customer'] ?? [], array_flip($schema->getColumnNames()));\n$customers = Customer::findAll($filters);","handlingStrategy":"validation","validationCode":"$columns = array_flip($modelClass::getTableSchema()->getColumnNames());\n$condition = array_intersect_key($condition, $columns);\n$models = $modelClass::findAll($condition);","typeGuard":null,"tryCatchPattern":"try {\n    $models = Model::findAll($condition);\n} catch (yii\\base\\InvalidArgumentException $e) {\n    if (strpos($e->getMessage(), 'is not a column name') !== false) {\n        $models = []; // reject untrusted filter keys instead of crashing\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Never pass request arrays directly to findOne/findAll; whitelist keys against schema columns","For joined columns use explicit alias prefixes declared in the query","Prefer find()->andWhere() for anything beyond plain column equality"],"tags":["active-record","condition","column-validation","sql-injection-guard"],"backgroundTag":"invalid-query-condition","analyzedSha":"66f00d18a29b520f85e8e8f1e32d1e7e7b556cac","analyzedAt":"2026-08-17T05:17:23.470Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}