{"record":{"id":"2ab0b67443904917","repo":"phalcon/cphalcon","slug":"cannot-resolve-attribute-attribute-in-the-mode","errorCode":null,"errorMessage":"Cannot resolve attribute '{attribute}' in the model '{className}'","messagePattern":"Cannot resolve attribute '(.+?)' in the model '(.+?)'","errorType":"exception","errorClass":"Phalcon\\Mvc\\Model\\Exceptions\\CannotResolveAttribute","httpStatus":null,"severity":"error","filePath":"phalcon/Mvc/Model.zep","lineNumber":5103,"sourceCode":"         */\n        if isset attributes[extraMethod] {\n            let field = extraMethod;\n        } else {\n            /**\n             * Lowercase the first letter of the extra-method\n             */\n            let extraMethodFirst = lcfirst(extraMethod);\n\n            if isset attributes[extraMethodFirst] {\n                let field = extraMethodFirst;\n            } else {\n                /**\n                 * Get the possible real method name\n                 */\n                let field = uncamelize(extraMethod);\n\n                if unlikely !isset attributes[field] {\n                    throw new CannotResolveAttribute(extraMethod, get_called_class());\n                }\n            }\n        }\n\n        /**\n         * Check if we have \"conditions\" and \"bind\" defined\n         */\n        fetch value, arguments[0];\n\n        if value !== null {\n            let params = [\n                 \"conditions\": \"[\" . field . \"] = ?0\",\n                 \"bind\"      : [value]\n            ];\n\n        } else {\n            let params = [\n                 \"conditions\": \"[\" . field . \"] IS NULL\"","sourceCodeStart":5085,"sourceCodeEnd":5121,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Mvc/Model.zep#L5085-L5121","documentation":"Thrown by Model::invokeFinder() (phalcon/Mvc/Model.zep:5103): the suffix of a magic finder cannot be resolved to any attribute of the model. The lookup tries the raw suffix, the lcfirst variant, and the uncamelized variant (e.g. 'FirstName' -> 'first_name') against the reverse column map or data types. The exception class is Phalcon\\Mvc\\Model\\Exceptions\\CannotResolveAttribute.","triggerScenarios":"Calling a finder whose attribute does not exist: Invoices::findFirstByCustmer(1) (typo), findByEmail() when the model/table has no 'email' column, or a finder built from user input where the attribute name is arbitrary.","commonSituations":"Typos in the magic method name; column renamed in a migration while old finder calls remain; finder names built dynamically from request parameters (also a safety concern); column map renaming that hides the real column name from uncamelize().","solutions":["Fix the attribute name in the method call to match a real column (mind snake_case uncamizing: findByFirstName maps to first_name)","Whitelist attribute names when finders are built from user input, then map to an explicit query","If the column was renamed, update the call site or keep an alias in the columnMap"],"exampleFix":"// before\n$invoice = Invoices::findFirstByCustmerId(7); // CannotResolveAttribute('CustmerId')\n\n// after\n$invoice = Invoices::findFirstByCustomerId(7);\n// with a column map ['customer_id' => 'custId'] you can also use:\n$invoice = Invoices::findFirstByCustId(7);","handlingStrategy":"type-guard","validationCode":"$allowed = array_keys($model->getModelsMetaData()->getReverseColumnMap($model) ?: $model->getModelsMetaData()->getDataTypes($model));\n$attr = 'custmer_id'; // from user input\nif (!in_array($attr, $allowed, true)) {\n    // reject before building a finder method name\n    throw new InvalidArgumentException(\"unknown attribute {$attr}\");\n}\n$method = 'findFirstBy' . ucfirst(camelize($attr));","typeGuard":"function isValidFinderAttribute(string $model, string $attribute): bool\n{\n    $meta = (new $model)->getModelsMetaData();\n    $attrs = $meta->getReverseColumnMap(new $model) ?: $meta->getDataTypes(new $model);\n    return isset($attrs[$attribute]) || isset($attrs[lcfirst($attribute)]) || isset($attrs[uncamelize($attribute)]);\n}","tryCatchPattern":"try {\n    $invoice = Invoices::findFirstByCustmerId(7);\n} catch (\\Phalcon\\Mvc\\Model\\Exceptions\\CannotResolveAttribute $e) {\n    // attribute name typo: fall back to an explicit query or return not-found\n    $invoice = Invoices::findFirst(['customer_id = ?0', 'bind' => [7]]);\n}","preventionTips":["Never build finder names straight from user input; validate against metadata first","Remember the uncamelize rule: findByFirstName -> first_name, so column-map aliases change resolution","Add PHPStan/custom lint for magic finder calls so typos surface at CI time"],"tags":["phalcon","orm","magic-finder","attribute","uncamelize"],"backgroundTag":"orm-unknown-column","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}