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
- Supply 'columns' as a list of Phalcon\Db\Column objects: $definition['columns'] = [new Column('id', ['type' => Column::TYPE_INTEGER, 'primary' => true])]
- Skip the createTable() call entirely when the columns list is empty — an empty array of columns is never valid
- 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
- Reject empty column lists in your migration runner before calling createTable()
- Generate DDL from validated metadata, not request data
- Smoke-test migrations against a scratch database in CI
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
- The index 'sql' is required in the definition array
- Unrecognized MySQL data type at column {}
- The index 'columns' is required in the definition array
- The table must contain at least one column
- The index 'sql' is required in the definition array
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/22fac8aa1c4aad9e.
Report an issue: GitHub.