{"record":{"id":"018d2d786b442060","repo":"phalcon/cphalcon","slug":"index-definition-directions-key-must-be-an-array","errorCode":null,"errorMessage":"Index definition 'directions' key must be an array","messagePattern":"Index definition 'directions' key must be an array","errorType":"exception","errorClass":"Phalcon\\Db\\Exceptions\\InvalidIndexDirections","httpStatus":null,"severity":"error","filePath":"phalcon/Db/Index.zep","lineNumber":155,"sourceCode":"\n        if isset columnsOrDefinition[\"columns\"] {\n            if unlikely typeof columnsOrDefinition[\"columns\"] != \"array\" {\n                throw new InvalidIndexColumns();\n            }\n\n            let this->columns = columnsOrDefinition[\"columns\"];\n\n            if fetch definitionType, columnsOrDefinition[\"type\"] {\n                let this->type = (string) definitionType;\n            }\n\n            if fetch invisible, columnsOrDefinition[\"invisible\"] {\n                let this->invisible = (bool) invisible;\n            }\n\n            if fetch directions, columnsOrDefinition[\"directions\"] {\n                if unlikely typeof directions != \"array\" {\n                    throw new InvalidIndexDirections();\n                }\n\n                let this->directions = directions;\n            }\n\n            if fetch where, columnsOrDefinition[\"where\"] {\n                if unlikely typeof where != \"string\" {\n                    throw new InvalidIndexWhere();\n                }\n\n                let this->where = where;\n            }\n\n            if fetch concurrent, columnsOrDefinition[\"concurrently\"] {\n                let this->concurrent = (bool) concurrent;\n            }\n        } else {\n            let this->columns = columnsOrDefinition;","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Db/Index.zep#L137-L173","documentation":"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.","triggerScenarios":"['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.","commonSituations":"Descending single-column indexes defined in YAML/JSON; definitions passed through string templates; per-column metadata generated from user input.","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"],"exampleFix":"// before\nnew Index('idx_created', ['columns' => ['created_at'], 'directions' => 'DESC']);\n\n// after\nnew Index('idx_created', ['columns' => ['created_at'], 'directions' => ['DESC']]);","handlingStrategy":"type-guard","validationCode":"if (isset($definition['directions']) && !is_array($definition['directions'])) {\n    $definition['directions'] = [$definition['directions']]; // or throw\n}\n$index = new \\Phalcon\\Db\\Index('idx_created', $definition);","typeGuard":"function isValidIndexDefinition(array $def): bool\n{\n    return !isset($def['columns'])\n        || (is_array($def['columns'])\n            && (!isset($def['directions']) || is_array($def['directions']))\n            && (!isset($def['where']) || is_string($def['where'])));\n}","tryCatchPattern":"try {\n    $index = new \\Phalcon\\Db\\Index('idx_created', $definition);\n} catch (\\Phalcon\\Db\\Exceptions\\InvalidIndexDirections $e) {\n    throw new InvalidArgumentException(\"Index 'directions' must be an array like ['DESC']\", 0, $e);\n}","preventionTips":["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"],"tags":["phalcon-db","index","schema-definition","migrations"],"backgroundTag":"invalid-index-definition","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}