yiisoft/yii2 · error · InvalidConfigException
The "sql" property must be set.
Error message
The "sql" property must be set.
What it means
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.
Source
Thrown at framework/data/SqlDataProvider.php:101
* @var string|callable|null the column that is used as the key of the data models.
* This can be either a column name, or a callable that returns the key value of a given data model.
*
* If this is not set, the keys of the [[models]] array will be used.
*/
public $key;
/**
* Initializes the DB connection component.
* This method will initialize the [[db]] property to make sure it refers to a valid DB connection.
* @throws InvalidConfigException if [[db]] is invalid.
*/
public function init()
{
parent::init();
$this->db = Instance::ensure($this->db, Connection::className());
if ($this->sql === null) {
throw new InvalidConfigException('The "sql" property must be set.');
}
}
/**
* {@inheritdoc}
*/
protected function prepareModels()
{
$sort = $this->getSort();
$pagination = $this->getPagination();
if ($pagination === false && $sort === false) {
return $this->db->createCommand($this->sql, $this->params)->queryAll();
}
$sql = $this->sql;
$orders = [];
$limit = $offset = null;
View on GitHub (pinned to 66f00d18a2)
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
Example fix
// before
$provider = new SqlDataProvider([
'db' => $db,
]);
// after
$provider = new SqlDataProvider([
'db' => $db,
'sql' => 'SELECT * FROM {{%post}} WHERE status = :status',
'params' => [':status' => 1],
]); Defensive patterns
Strategy: validation
Validate before calling
$config = ['class' => SqlDataProvider::class, 'db' => $db];
if (!isset($config['sql']) || !is_string($config['sql']) || $config['sql'] === '') {
throw new InvalidArgumentException('SqlDataProvider requires a non-empty "sql" string.');
}
$provider = Yii::createObject($config); Try / catch
try {
$provider = Yii::createObject($config);
} catch (yii\base\InvalidConfigException $e) {
// log config origin and fail loudly during development
Yii::error('SqlDataProvider misconfigured: ' . $e->getMessage(), 'data');
throw $e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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'.
Related errors
- Cost must be between 4 and 31.
- The "basePath" property must be set.
- The "baseUrl" property must be set.
- Unsupported type '{type}'
- DbDependency::sql must be set.
AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17).
Data as JSON: /api/errors/c99de4360c734844.
Report an issue: GitHub.