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

  1. Set the sql property in the configuration: ['class' => SqlDataProvider::class, 'sql' => 'SELECT * FROM {{%post}}']
  2. If SQL is built dynamically, verify the variable is a non-null string before constructing the provider
  3. Bind dynamic values through the params property instead of concatenating them into sql
  4. 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

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


AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17). Data as JSON: /api/errors/c99de4360c734844. Report an issue: GitHub.