phalcon/cphalcon · error · Phalcon\Mvc\Model\Exceptions\DataTypeNotDefined

Column ' ' have not defined a data type in

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.

Solutions

  1. Clear the model metadata cache so getDataTypes() covers every attribute
  2. In manual metadata, add the field to the dataTypes map (e.g. Column::TYPE_VARCHAR) alongside bind types
  3. 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 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


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/1bc6ca4c9025fac3. Report an issue: GitHub.

Appendix: 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)