phalcon/cphalcon · error · Phalcon\Db\Exceptions\InvalidIndexDirections
Index definition 'directions' key must be an array
Error message
Index definition 'directions' key must be an array
What it means
In the definition-array form of Index::__construct(), an optional 'directions' key (per-column ASC/DESC for the index) must be an array. A scalar — e.g. the string 'DESC' instead of ['DESC'] — throws InvalidIndexDirections.
Source
Thrown at phalcon/Db/Index.zep:155
if isset columnsOrDefinition["columns"] {
if unlikely typeof columnsOrDefinition["columns"] != "array" {
throw new InvalidIndexColumns();
}
let this->columns = columnsOrDefinition["columns"];
if fetch definitionType, columnsOrDefinition["type"] {
let this->type = (string) definitionType;
}
if fetch invisible, columnsOrDefinition["invisible"] {
let this->invisible = (bool) invisible;
}
if fetch directions, columnsOrDefinition["directions"] {
if unlikely typeof directions != "array" {
throw new InvalidIndexDirections();
}
let this->directions = directions;
}
if fetch where, columnsOrDefinition["where"] {
if unlikely typeof where != "string" {
throw new InvalidIndexWhere();
}
let this->where = where;
}
if fetch concurrent, columnsOrDefinition["concurrently"] {
let this->concurrent = (bool) concurrent;
}
} else {
let this->columns = columnsOrDefinition;View on GitHub (pinned to b7419de9cd)
Solutions
- Pass directions as an array: 'directions' => ['DESC']
- Normalize scalars: $dirs = is_array($dirs) ? $dirs : [$dirs]
- Validate the definition with a type guard before constructing Index
Example fix
// before
new Index('idx_created', ['columns' => ['created_at'], 'directions' => 'DESC']);
// after
new Index('idx_created', ['columns' => ['created_at'], 'directions' => ['DESC']]); Defensive patterns
Strategy: type-guard
Validate before calling
if (isset($definition['directions']) && !is_array($definition['directions'])) {
$definition['directions'] = [$definition['directions']]; // or throw
}
$index = new \Phalcon\Db\Index('idx_created', $definition); Type guard
function isValidIndexDefinition(array $def): bool
{
return !isset($def['columns'])
|| (is_array($def['columns'])
&& (!isset($def['directions']) || is_array($def['directions']))
&& (!isset($def['where']) || is_string($def['where'])));
} Try / catch
try {
$index = new \Phalcon\Db\Index('idx_created', $definition);
} catch (\Phalcon\Db\Exceptions\InvalidIndexDirections $e) {
throw new InvalidArgumentException("Index 'directions' must be an array like ['DESC']", 0, $e);
} Prevention
- Per-column metadata in index definitions is always a list — use arrays even for one column
- Watch YAML single-item sequences collapsing to scalars
- Validate the whole definition with one guard before constructing Index
When it happens
Trigger: ['columns' => ['created_at'], 'directions' => 'DESC']; single-element direction lists collapsed to strings by config loaders; values copied from docs where the array brackets were lost.
Common situations: Descending single-column indexes defined in YAML/JSON; definitions passed through string templates; per-column metadata generated from user input.
Related errors
- Index definition 'columns' key must be an array
- Index definition 'where' key must be a string
- Referenced table is required
- Foreign key columns are required
- Referenced columns of the foreign key are required
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/018d2d786b442060.
Report an issue: GitHub.