{"record":{"id":"1bc6ca4c9025fac3","repo":"phalcon/cphalcon","slug":"column-column-have-not-defined-a-data-type-in","errorCode":null,"errorMessage":"Column '{column}' have not defined a data type in '{className}'","messagePattern":"Column '(.+?)' have not defined a data type in '(.+?)'","errorType":"exception","errorClass":"Phalcon\\Mvc\\Model\\Exceptions\\DataTypeNotDefined","httpStatus":null,"severity":"error","filePath":"phalcon/Mvc/Model.zep","lineNumber":4479,"sourceCode":"                        if !fetch snapshotValue, snapshot[attributeField] {\n                            let changed = true;\n                        } else {\n                            /**\n                             * See https://github.com/phalcon/cphalcon/issues/3247\n                             * Take a TEXT column with value '4' and replace it by\n                             * the value '4.0'. For PHP '4' and '4.0' are the same.\n                             * We can't use simple comparison...\n                             *\n                             * We must use the type of snapshotValue.\n                             */\n                            if value === null {\n                                let changed = snapshotValue !== null;\n                            } else {\n                                if snapshotValue === null {\n                                    let changed = true;\n                                } else {\n                                    if unlikely !fetch dataType, dataTypes[field] {\n                                        throw new DataTypeNotDefined(field, get_class(this));\n                                    }\n\n                                    /**\n                                    * Get actual values before comparison\n                                    */\n                                    if is_object(snapshotValue) && snapshotValue instanceof RawValue {\n                                        let snapshotValue = snapshotValue->getValue();\n                                    }\n\n                                    let updateValue = value;\n                                    if is_object(value) && value instanceof RawValue {\n                                        let updateValue = value->getValue();\n                                    }\n\n                                    switch dataType {\n\n                                        case Column::TYPE_BOOLEAN:\n                                            let changed = (bool) snapshotValue !== (bool) updateValue;","sourceCodeStart":4461,"sourceCodeEnd":4497,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Mvc/Model.zep#L4461-L4497","documentation":"Thrown by Model::doLowUpdate() (phalcon/Mvc/Model.zep:4479) in the dynamic-update branch: to decide whether a field changed, the code compares the current value with the kept snapshot using the field's data type, and metaData->getDataTypes() has no entry for that field. The exception class is Phalcon\\Mvc\\Model\\Exceptions\\DataTypeNotDefined. The comparison path only runs when a snapshot value exists and both values are non-null.","triggerScenarios":"Updating a model with dynamic update plus keep snapshots (modelsManager->keepSnapshots(true)) where the data-types metadata map lacks a field. The snapshot comparison at the switch on dataType then cannot run.","commonSituations":"Adding a column to the table and not flushing metadata before editing loaded models; custom metadata providers that implement getBindTypes() but not (or incompletely) getDataTypes(); schema drift between the environment that filled the cache and the current one.","solutions":["Clear the model metadata cache so getDataTypes() covers every attribute","In manual metadata, add the field to the dataTypes map (e.g. Column::TYPE_VARCHAR) alongside bind types","Ensure keepSnapshots/dynamicUpdate models run against metadata generated from the same schema version"],"exampleFix":"// before\n// custom metadata missing data type for 'coupon_code'\n$invoice->couponCode = 'SAVE10';\n$invoice->save(); // DataTypeNotDefined during snapshot compare\n\n// after\n$this->data['dataTypes'] = [\n    ...\n    'coupon_code' => Column::TYPE_VARCHAR,\n];\n$invoice->save();","handlingStrategy":"validation","validationCode":"$metaData = $model->getModelsMetaData();\n$dataTypes = $metaData->getDataTypes($model);\nforeach ($metaData->getNonPrimaryKeyAttributes($model) as $field) {\n    if (!isset($dataTypes[$field])) {\n        // dynamic-update comparison needs a data type for every field\n        $metaData->reset();\n        break;\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When using keepSnapshots + dynamicUpdate, keep getDataTypes() complete in custom providers","Flush metadata cache after DDL changes before any record is loaded and edited","Add a snapshot-change test per model to catch this before production"],"tags":["phalcon","orm","update","data-type","snapshot","metadata"],"backgroundTag":"orm-metadata-schema-mismatch","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}