phalcon/cphalcon · error · MissingDefinitionKey

The index 'columns' is required in the definition array

Error message

The index 'columns' is required in the definition array

What it means

Mysql dialect's createTable() throws MissingDefinitionKey when the definition array passed to $adapter->createTable() has no 'columns' key. A CREATE TABLE must contain at least one column definition; the dialect checks this first, before looking at 'indexes', 'references', or 'options'.

Source

Thrown at phalcon/Db/Dialect/Mysql.zep:188

     */
    public function addPrimaryKey( string tableName,  string schemaName, <IndexInterface> index) -> string
    {
        return "ALTER TABLE " . this->prepareTable(tableName, schemaName) . " ADD PRIMARY KEY (" . this->getColumnList(index->getColumns()) . ")";
    }

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

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

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

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

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

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Supply 'columns' as a list of Phalcon\Db\Column objects: $definition['columns'] = [new Column('id', ['type' => Column::TYPE_INTEGER, 'primary' => true])]
  2. Skip the createTable() call entirely when the columns list is empty — an empty array of columns is never valid
  3. Validate the migration/source data that produced the definition

Example fix

// before
$connection->createTable('robots', null, [
    'options' => ['ENGINE' => 'InnoDB'],
]);

// after
$connection->createTable('robots', null, [
    'columns' => [
        new Column('id', ['type' => Column::TYPE_INTEGER, 'primary' => true]),
        new Column('name', ['type' => Column::TYPE_VARCHAR, 'size' => 100]),
    ],
    'options' => ['ENGINE' => 'InnoDB'],
]);
Defensive patterns

Strategy: validation

Validate before calling

if (empty($definition['columns']) || !is_array($definition['columns'])) {
    throw new InvalidArgumentException('createTable requires a non-empty "columns" array of Column objects');
}

Type guard

function isCreatableTableDefinition(array $definition): bool
{
    return isset($definition['columns'])
        && is_array($definition['columns'])
        && $definition['columns'] !== []
        && array_reduce($definition['columns'], fn($ok, $c) => $ok && $c instanceof \Phalcon\Db\Column, true);
}

Try / catch

try {
    $connection->createTable($table, $schema, $definition);
} catch (\Phalcon\Db\Exceptions\MissingDefinitionKey $e) {
    throw new RuntimeException("Cannot create table {$table}: " . $e->getMessage(), 0, $e);
}

Prevention

When it happens

Trigger: Calling $adapter->createTable('robots', null, []) or with a definition containing only 'indexes'/'options'; building the definition array from migration data where the columns list came back empty or was stored under another key.

Common situations: Migration scripts that iterate over metadata and pass an empty definition when a table has no columns recorded; programmatic table creation from config; misspelling the key ('column', 'fields').

Related errors


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