phalcon/cphalcon · error · Phalcon\Db\Exceptions\MissingDefinitionKey

The index 'columns' is required in the definition array

Error message

The index 'columns' is required in the definition array

What it means

Thrown by Phalcon\Db\Dialect\Sqlite::createTable() when the $definition array contains no 'columns' key. The SQLite dialect always builds CREATE TABLE statements from an array of Phalcon\Db\Column objects, so a definition without columns cannot produce valid SQL. MissingDefinitionKey signals an incomplete schema definition array on the caller side, not a database failure.

Source

Thrown at phalcon/Db/Dialect/Sqlite.zep:163

     * Generates SQL to create a table
     */
    public function createTable( string tableName,  string schemaName,  array definition) -> string
    {
        var columns, table, temporary, options, createLines, columnLine,
            column, indexes, index, indexName, indexType, references, reference,
            defaultValue, referenceSql, onDelete, onUpdate, checks, check;
        bool hasPrimary;
        string sql;

        let table = this->prepareTable(tableName, schemaName);

        let temporary = false;
        if fetch options, definition["options"] {
            fetch temporary, options["temporary"];
        }

        if unlikely !fetch columns, definition["columns"] {
            throw new MissingDefinitionKey("columns");
        }

        /**
         * Create a temporary or normal table
         */
        if temporary {
            let sql = "CREATE TEMPORARY TABLE " . table;
        } else {
            let sql = "CREATE TABLE " . table;
        }

        let sql .= " (\n\t";

        let hasPrimary = false;
        let createLines = [];

        for column in columns {
            let columnLine = "`" . column->getName() . "` "

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Add a 'columns' key holding Phalcon\Db\Column objects: ['columns' => [new Column('id', ['type' => Column::TYPE_INTEGER, 'primary' => true]), ...]]
  2. Validate isset($definition['columns']) && is_array($definition['columns']) && $definition['columns'] !== [] before calling createTable()
  3. When deriving a new table from an existing one, build the array from $connection->describeColumns($table) and pass it under the 'columns' key

Example fix

// before
$sql = $dialect->createTable('posts', null, ['options' => ['temporary' => true]]);

// after
use Phalcon\Db\Column;
$sql = $dialect->createTable('posts', null, [
    'columns' => [
        new Column('id', ['type' => Column::TYPE_INTEGER, 'primary' => true]),
        new Column('title', ['type' => Column::TYPE_VARCHAR, 'size' => 255]),
    ],
]);
Defensive patterns

Strategy: validation

Validate before calling

if (!isset($definition['columns']) || !is_array($definition['columns']) || [] === $definition['columns']) {
    throw new InvalidArgumentException("createTable definition requires a non-empty 'columns' array");
}
$sql = $dialect->createTable('posts', null, $definition);

Try / catch

try {
    $sql = $dialect->createTable('posts', null, $definition);
} catch (\Phalcon\Db\Exceptions\MissingDefinitionKey $e) {
    throw new InvalidArgumentException('Invalid definition for table posts: ' . $e->getMessage(), 0, $e);
}

Prevention

When it happens

Trigger: Calling $dialect->createTable('posts', null, ['options' => ['temporary' => true]]) with no 'columns' entry; a definition whose key was typo'd ('Columns', 'fields') or removed by array_filter()/array_diff(); definitions built from YAML/JSON config where the columns entry was never set.

Common situations: Migration code that clones table definitions via describeColumns() and mangles keys; config-driven table creation where the source file lacks the columns entry; examples adapted from other dialects that pass only table options.

Related errors


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/9d2facaf4f56d9d3. Report an issue: GitHub.