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

Column '{column}' isn't part of the table columns in '{class

Error message

Column '{column}' isn't part of the table columns in '{className}'

What it means

Thrown by Model::has() (phalcon/Mvc/Model.zep:4775): while collecting bind types for the primary-key WHERE condition, metaData->getBindTypes() has no entry for a PK field. The exception class is Phalcon\Mvc\Model\Exceptions\ColumnNotInTableColumns. The message says 'table columns' because bind types mirror the introspected column list.

Source

Thrown at phalcon/Mvc/Model.zep:4775

                let value = null;

                if fetch value, this->{attributeField} {
                    /**
                     * We count how many fields are empty, if all fields are
                     * empty we don't perform an 'exist' check
                     */
                    if value === null || value === "" {
                        let numberEmpty++;
                    }

                    let uniqueParams[] = value;
                } else {
                    let uniqueParams[] = null,
                        numberEmpty++;
                }

                if unlikely !fetch type, bindDataTypes[field] {
                    throw new ColumnNotInTableColumns(field, get_class(this));
                }

                let uniqueTypes[] = type,
                    wherePk[]     = connection->escapeIdentifier(field) . " = ?";
            }

            /**
             * There are no primary key fields defined, assume the record does
             * not exist
             */
            if numberPrimary == numberEmpty {
                return false;
            }

            let joinWhere = join(" AND ", wherePk);

            /**
             * The unique key is composed of 3 parts uniqueKey, uniqueParams,

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Flush the model metadata cache after any PK-related DDL
  2. Add the PK to the bindTypes map in the custom metadata provider (BIND_PARAM_INT for numeric, BIND_PARAM_STR for uuid/text)
  3. Verify the model binds to the expected schema: getSchema()/getSource()

Example fix

// before
$metaData = new MyMetaData($cache);
// bindTypes: ['name' => Column::BIND_PARAM_STR] -- PK omitted
$product->save(); // ColumnNotInTableColumns('product_id') in has()

// after
// 'bindTypes' => ['product_id' => Column::BIND_PARAM_INT, 'name' => Column::BIND_PARAM_STR, ...]
$product->save();
Defensive patterns

Strategy: validation

Validate before calling

$metaData = $model->getModelsMetaData();
$bindTypes = $metaData->getBindTypes($model);
foreach ($metaData->getPrimaryKeyAttributes($model) as $pk) {
    if (!isset($bindTypes[$pk])) {
        // existence check cannot bind the WHERE; reset metadata
        $metaData->reset();
        break;
    }
}

Prevention

When it happens

Trigger: Any save() on a model whose bind-types metadata lacks a primary-key field: stale metadata cache after PK DDL, or a custom metadata provider whose bindTypes map omits the PK.

Common situations: PK column type changed (int to uuid) without a cache flush; manual metadata listing bind types for business columns only; metadata generated from a different table with the same name in another schema.

Related errors


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