phalcon/cphalcon · error · GeneratedDefaultConflict

Generated column cannot have a default value

Error message

Generated column cannot have a default value

What it means

Database-generated columns cannot also carry a DEFAULT value; the generation expression already determines the value. Phalcon\Db\Column therefore throws GeneratedDefaultConflict when a non-null 'generated' definition is combined with a non-null 'default'. It is the third consistency check in the constructor, after the type check and the auto-increment conflict.

Source

Thrown at phalcon/Db/Column.zep:734

        }

        /**
         * Generated/computed column expression. When a non-empty string is
         * provided the column is marked as generated and DEFAULT /
         * AUTO_INCREMENT are no longer compatible at the dialect level.
         */
        if fetch generated, definition["generated"] {
            if generated !== null {
                if unlikely typeof generated != "string" {
                    throw new InvalidGenerationExpression();
                }

                if unlikely this->autoIncrement {
                    throw new GeneratedAutoIncrementConflict();
                }

                if unlikely this->defaultValue !== null {
                    throw new GeneratedDefaultConflict();
                }

                let this->generated = generated;
            }
        }

        /**
         * Storage flag for generated columns. true = STORED, false = VIRTUAL.
         */
        if fetch generationStored, definition["generationStored"] {
            let this->generationStored = (bool) generationStored;
        }

        /**
         * Whether the column is INVISIBLE (MySQL 8.0.23+).
         */
        if fetch invisible, definition["invisible"] {
            let this->invisible = (bool) invisible;

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Remove 'default' from the generated column's definition.
  2. If a fallback is needed, express it inside the generation expression (e.g. COALESCE(price * qty, 0)).
  3. Strip 'default' and 'autoIncrement' keys programmatically when marking a column generated.

Example fix

// before
$column = new Column('total', [
    'type'      => Column::TYPE_DECIMAL,
    'size'      => 10,
    'scale'     => 2,
    'default'   => 0,
    'generated' => 'price * qty', // throws GeneratedDefaultConflict
]);

// after
$column = new Column('total', [
    'type'      => Column::TYPE_DECIMAL,
    'size'      => 10,
    'scale'     => 2,
    'generated' => 'COALESCE(price * qty, 0)',
]);
Defensive patterns

Strategy: validation

Validate before calling

if (isset($definition['generated']) && $definition['generated'] !== null
    && array_key_exists('default', $definition)
    && $definition['default'] !== null) {
    unset($definition['default']); // or throw your own error
}
$column = new Column('total', $definition);

Prevention

When it happens

Trigger: new Column('total', ['type' => Column::TYPE_DECIMAL, 'default' => 0, 'generated' => 'price * qty']); blueprint columns that ship a default and later gain a generation expression; definition mergers keeping the old 'default' key.

Common situations: Reusing a template column (with default) for a computed column; seed-style schemas where every column has a fallback default; migration tools merging old and new definitions instead of replacing.

Related errors


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