{"record":{"id":"ec08e7048236b615","repo":"phalcon/cphalcon","slug":"index-definition-columns-key-must-be-an-array","errorCode":null,"errorMessage":"Index definition 'columns' key must be an array","messagePattern":"Index definition 'columns' key must be an array","errorType":"exception","errorClass":"Phalcon\\Db\\Exceptions\\InvalidIndexColumns","httpStatus":null,"severity":"error","filePath":"phalcon/Db/Index.zep","lineNumber":140,"sourceCode":"\n    /**\n     * Phalcon\\Db\\Index constructor.\n     *\n     * Accepts either the legacy positional form `(name, columns, type)` or a\n     * definition-array form `(name, [\"columns\" => [...], \"type\" => \"...\",\n     * \"invisible\" => true, ...])`. Detection is based on the presence of a\n     * `columns` key in the second argument; when present, the third\n     * positional `type` argument is ignored in favor of the definition.\n     */\n    public function __construct( string name,  array columnsOrDefinition, string type = \"\")\n    {\n        var definitionType, invisible, directions, where, concurrent;\n\n        let this->name = name;\n\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;","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Db/Index.zep#L122-L158","documentation":"Phalcon\\Db\\Index::__construct() accepts either a plain column list or a definition array detected by the presence of a 'columns' key. In the definition form, 'columns' must itself be an array of column names; a scalar — most commonly a single string — throws InvalidIndexColumns.","triggerScenarios":"new Index('idx_user', ['columns' => 'user_id', 'type' => 'INDEX']); definitions built from JSON/YAML where a one-element list collapsed to a scalar; ['columns' => implode(',', $cols)].","commonSituations":"Single-column indexes declared in config files; YAML loaders that inline single-item sequences as plain strings; migration definitions assembled from user input without normalization.","solutions":["Wrap the value in an array: ['columns' => ['user_id']]","Normalize before construction: $cols = is_array($cols) ? $cols : [$cols]","Guard definition builders with is_array($definition['columns']) assertions"],"exampleFix":"// before\nnew Index('idx_user', ['columns' => 'user_id', 'type' => 'INDEX']);\n\n// after\nnew Index('idx_user', ['columns' => ['user_id'], 'type' => 'INDEX']);","handlingStrategy":"type-guard","validationCode":"if (isset($definition['columns']) && !is_array($definition['columns'])) {\n    $definition['columns'] = (array) $definition['columns']; // or throw\n}\n$index = new \\Phalcon\\Db\\Index('idx_user', $definition);","typeGuard":"function isValidIndexDefinition(array $def): bool\n{\n    if (!isset($def['columns'])) {\n        return true; // positional column-list form\n    }\n    return is_array($def['columns']);\n}","tryCatchPattern":"try {\n    $index = new \\Phalcon\\Db\\Index('idx_user', $definition);\n} catch (\\Phalcon\\Db\\Exceptions\\InvalidIndexColumns $e) {\n    throw new InvalidArgumentException('Index columns must be an array of names', 0, $e);\n}","preventionTips":["Always wrap column names in arrays, even for single-column indexes","Normalize config-sourced definitions: cast scalar 'columns' to an array before use","Unit-test migration definition builders to emit arrays for every key"],"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"}