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
The PostgreSQL dialect's createTable() throws MissingDefinitionKey when the definition array passed to $adapter->createTable() lacks 'columns'. As with MySQL, at least one Phalcon\Db\Column is required before any 'indexes', 'references', or 'options' are processed; the check happens first thing in the method.
Source
Thrown at phalcon/Db/Dialect/Postgresql.zep:162
*/
public function addPrimaryKey( string tableName, string schemaName, <IndexInterface> index) -> string
{
return "ALTER TABLE " . this->prepareTable(tableName, schemaName) . " ADD CONSTRAINT \"" . tableName . "_PRIMARY\" 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, indexType, onDelete, onUpdate,
columnDefinition, checks, check, tableComment;
array createLines, primaryColumns;
string indexSql, indexSqlAfterCreate, columnLine, 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"];
fetch tableComment, options["TABLE_COMMENT"];
}
/**
* 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
- Provide 'columns' as Column objects: $definition['columns'] = [new Column('id', ['type' => Column::TYPE_SERIAL, 'primary' => true]), ...]
- Skip createTable() when the computed columns list is empty
- Verify the source metadata/migration that generated the definition
Example fix
// before
$connection->createTable('robots', 'public', [
'options' => ['TABLE_COMMENT' => 'robots'],
]);
// after
$connection->createTable('robots', 'public', [
'columns' => [
new Column('id', ['type' => Column::TYPE_SERIAL, 'primary' => true]),
new Column('name', ['type' => Column::TYPE_VARCHAR, 'size' => 100]),
],
]); 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');
} Type guard
function isCreatableTableDefinition(array $definition): bool
{
return isset($definition['columns'])
&& is_array($definition['columns'])
&& $definition['columns'] !== [];
} 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
- Refuse to run migrations whose computed column list is empty
- Validate generated definitions against a fixed schema before executing DDL
- Run schema-sync tools in dry-run mode first
When it happens
Trigger: Calling $adapter->createTable('robots', 'public', ['indexes' => [...]]) with no 'columns'; migration generators emitting definitions without a columns list for empty tables; key misspelled as 'column' or 'fields'.
Common situations: Schema-sync tooling that diffs metadata and produces empty definitions; copying MySQL migration code with a renamed key; programmatic DDL from config files.
Related errors
- The index 'columns' is required in the definition array
- The index 'sql' is required in the definition array
- Unrecognized PostgreSQL data type at column {}
- 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/9fd62ad32f4f0ab0.
Report an issue: GitHub.