phalcon/cphalcon · error · Phalcon\Mvc\Model\Exceptions\DataTypeNotDefined
Column '{column}' have not defined a data type in '{classNam
Error message
Column '{column}' have not defined a data type in '{className}' What it means
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.
Source
Thrown at phalcon/Mvc/Model.zep:4479
if !fetch snapshotValue, snapshot[attributeField] {
let changed = true;
} else {
/**
* See https://github.com/phalcon/cphalcon/issues/3247
* Take a TEXT column with value '4' and replace it by
* the value '4.0'. For PHP '4' and '4.0' are the same.
* We can't use simple comparison...
*
* We must use the type of snapshotValue.
*/
if value === null {
let changed = snapshotValue !== null;
} else {
if snapshotValue === null {
let changed = true;
} else {
if unlikely !fetch dataType, dataTypes[field] {
throw new DataTypeNotDefined(field, get_class(this));
}
/**
* Get actual values before comparison
*/
if is_object(snapshotValue) && snapshotValue instanceof RawValue {
let snapshotValue = snapshotValue->getValue();
}
let updateValue = value;
if is_object(value) && value instanceof RawValue {
let updateValue = value->getValue();
}
switch dataType {
case Column::TYPE_BOOLEAN:
let changed = (bool) snapshotValue !== (bool) updateValue;View on GitHub (pinned to b7419de9cd)
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
Example fix
// before
// custom metadata missing data type for 'coupon_code'
$invoice->couponCode = 'SAVE10';
$invoice->save(); // DataTypeNotDefined during snapshot compare
// after
$this->data['dataTypes'] = [
...
'coupon_code' => Column::TYPE_VARCHAR,
];
$invoice->save(); Defensive patterns
Strategy: validation
Validate before calling
$metaData = $model->getModelsMetaData();
$dataTypes = $metaData->getDataTypes($model);
foreach ($metaData->getNonPrimaryKeyAttributes($model) as $field) {
if (!isset($dataTypes[$field])) {
// dynamic-update comparison needs a data type for every field
$metaData->reset();
break;
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Identity column '{identityField}' isn't part of the table co
- Column '{column}' isn't part of the table columns in '{class
- The meta-data is invalid or is corrupt
- A dependency injection container is required to access inter
- Invalid meta-data for model {modelName}
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/1bc6ca4c9025fac3.
Report an issue: GitHub.