{"record":{"id":"c99de4360c734844","repo":"yiisoft/yii2","slug":"the-sql-property-must-be-set","errorCode":null,"errorMessage":"The \"sql\" property must be set.","messagePattern":"The \"sql\" property must be set\\.","errorType":"exception","errorClass":"InvalidConfigException","httpStatus":null,"severity":"error","filePath":"framework/data/SqlDataProvider.php","lineNumber":101,"sourceCode":"     * @var string|callable|null the column that is used as the key of the data models.\n     * This can be either a column name, or a callable that returns the key value of a given data model.\n     *\n     * If this is not set, the keys of the [[models]] array will be used.\n     */\n    public $key;\n\n\n    /**\n     * Initializes the DB connection component.\n     * This method will initialize the [[db]] property to make sure it refers to a valid DB connection.\n     * @throws InvalidConfigException if [[db]] is invalid.\n     */\n    public function init()\n    {\n        parent::init();\n        $this->db = Instance::ensure($this->db, Connection::className());\n        if ($this->sql === null) {\n            throw new InvalidConfigException('The \"sql\" property must be set.');\n        }\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    protected function prepareModels()\n    {\n        $sort = $this->getSort();\n        $pagination = $this->getPagination();\n        if ($pagination === false && $sort === false) {\n            return $this->db->createCommand($this->sql, $this->params)->queryAll();\n        }\n\n        $sql = $this->sql;\n        $orders = [];\n        $limit = $offset = null;\n","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/yiisoft/yii2/blob/66f00d18a29b520f85e8e8f1e32d1e7e7b556cac/framework/data/SqlDataProvider.php#L83-L119","documentation":"SqlDataProvider fetches rows by executing the raw SQL statement held in its public $sql property. During init() the provider first resolves the db component via Instance::ensure, then requires that $sql is not null; if it is, InvalidConfigException is thrown. The check fires at component initialization, so the provider fails before any query runs.","triggerScenarios":"Constructing the provider with a config array that omits the 'sql' key, e.g. new SqlDataProvider(['db' => $db]); Yii::createObject(['class' => SqlDataProvider::class]) without sql; passing a variable as 'sql' that evaluated to null; registering SqlDataProvider as an application/component without an sql value.","commonSituations":"Copy-pasting an ActiveDataProvider config and changing only the class name; building the config dynamically where the SQL string comes from another method that returned null; typo'd key such as 'sqlQuery' or 'SQL' instead of 'sql'.","solutions":["Set the sql property in the configuration: ['class' => SqlDataProvider::class, 'sql' => 'SELECT * FROM {{%post}}']","If SQL is built dynamically, verify the variable is a non-null string before constructing the provider","Bind dynamic values through the params property instead of concatenating them into sql","If you already hold an ActiveQuery or AR find() result, use ActiveDataProvider with the 'query' option instead"],"exampleFix":"// before\n$provider = new SqlDataProvider([\n    'db' => $db,\n]);\n\n// after\n$provider = new SqlDataProvider([\n    'db' => $db,\n    'sql' => 'SELECT * FROM {{%post}} WHERE status = :status',\n    'params' => [':status' => 1],\n]);","handlingStrategy":"validation","validationCode":"$config = ['class' => SqlDataProvider::class, 'db' => $db];\nif (!isset($config['sql']) || !is_string($config['sql']) || $config['sql'] === '') {\n    throw new InvalidArgumentException('SqlDataProvider requires a non-empty \"sql\" string.');\n}\n$provider = Yii::createObject($config);","typeGuard":null,"tryCatchPattern":"try {\n    $provider = Yii::createObject($config);\n} catch (yii\\base\\InvalidConfigException $e) {\n    // log config origin and fail loudly during development\n    Yii::error('SqlDataProvider misconfigured: ' . $e->getMessage(), 'data');\n    throw $e;\n}","preventionTips":["Always build SqlDataProvider configs through one factory method that asserts the sql key","Fail fast at boot when sql-dependent widgets are registered without configuration","Prefer params binding over string-built SQL so config problems surface as missing sql, not broken SQL"],"tags":["configuration","data-provider","sql","yii2"],"backgroundTag":"missing-required-config","analyzedSha":"66f00d18a29b520f85e8e8f1e32d1e7e7b556cac","analyzedAt":"2026-08-17T05:17:23.470Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}