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
Dialect::select() throws MissingDefinitionKey (extends Phalcon\Db\Exception) when the definition array lacks the 'columns' key. Even for SELECT * the compiler requires an explicit columns entry (e.g. a scalar expression wrapping '*'); it will not guess a default projection. It fails immediately at the top of select(), after the 'tables' check.
Source
Thrown at phalcon/Db/Dialect.zep:609
{
return "ROLLBACK TO SAVEPOINT " . name;
}
/**
* Builds a SELECT statement
*/
public function select( array definition) -> string
{
var tables, columns, sql, distinct, joins, where, escapeChar, groupBy,
having, orderBy, limit, forUpdate, bindCounts;
array parts;
if unlikely !fetch tables, definition["tables"] {
throw new MissingDefinitionKey("tables");
}
if unlikely !fetch columns, definition["columns"] {
throw new MissingDefinitionKey("columns");
}
if fetch distinct, definition["distinct"] {
if distinct {
let sql = "SELECT DISTINCT";
} else {
let sql = "SELECT ALL";
}
} else {
let sql = "SELECT";
}
fetch bindCounts, definition["bindCounts"];
if typeof bindCounts !== "array" {
let bindCounts = [];
}
let escapeChar = this->escapeChar;View on GitHub (pinned to b7419de9cd)
Solutions
- Add a 'columns' entry; for all columns use a scalar expression: definition['columns'] = [['type' => 'scalar', 'value' => '*']] or a list of column names
- Default the key in your builder code before calling select(): $definition['columns'] ??= [['type' => 'scalar', 'value' => '*']]
- Verify no branch of your definition-building code drops or renames 'columns'
- Use Phalcon\Db\QueryBuilder, which normalizes columns for you
Example fix
// before
$sql = $dialect->select(['tables' => ['robots']]);
// after
$sql = $dialect->select([
'tables' => ['robots'],
'columns' => [['type' => 'scalar', 'value' => '*']],
]); Defensive patterns
Strategy: validation
Validate before calling
$definition['columns'] = $definition['columns'] ?? [['type' => 'scalar', 'value' => '*']];
if (!is_array($definition['columns'])) {
throw new InvalidArgumentException('"columns" must be an array of expressions');
} Try / catch
try {
$sql = $dialect->select($definition);
} catch (\Phalcon\Db\Exceptions\MissingDefinitionKey $e) {
throw new InvalidArgumentException('Bad select definition: ' . $e->getMessage(), 0, $e);
} Prevention
- Default 'columns' to a '*' scalar expression in your query builder
- Never unset or rename 'columns' when post-processing definitions
- Use Query Builder so projection handling is done for you
When it happens
Trigger: Calling $dialect->select(['tables' => ['robots']]) without a 'columns' key. Also passing columns under a wrong key ('fields', 'select'), or unsetting definition['columns'] in a conditional before the call.
Common situations: Building a generic query layer where columns are optional in the calling API; partial definition arrays assembled from multiple sources; code copied from SELECT examples that omitted the projection.
Related errors
- The index 'tables' is required in the definition array
- Operator '{}' is not supported by this SQL dialect
- Invalid SQL-GROUP-BY expression
- Invalid SQL-list expression
- Invalid SQL-ORDER-BY expression
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/bfe1a827e5eb5c84.
Report an issue: GitHub.