phalcon/cphalcon · error · Phalcon\Db\Exceptions\UnrecognizedDataType

Unrecognized SQLite data type at column {column}

Error message

Unrecognized SQLite data type at column {column}

What it means

Thrown while the SQLite dialect renders column DDL: the Column object's type constant fell through the dialect's type switch and no column SQL had been generated, so the dialect cannot express the column in CREATE TABLE/ADD COLUMN. UnrecognizedDataType carries the dialect name ('SQLite') and the offending column name.

Source

Thrown at phalcon/Db/Dialect/Sqlite.zep:583

            case Column::TYPE_TINYBLOB:
                if empty columnSql {
                    let columnSql .= "TINYBLOB";
                }

                break;

            case Column::TYPE_VARCHAR:
                if empty columnSql {
                    let columnSql .= "VARCHAR";
                }

                let columnSql .= this->getColumnSize(column);

                break;

            default:
                if empty columnSql {
                    throw new UnrecognizedDataType("SQLite", column->getName());
                }

                let typeValues = column->getTypeValues();
                if !empty typeValues {
                    if typeof typeValues == "array" {
                        var value, valueSql;

                        let valueSql = "";

                        for value in typeValues {
                            let valueSql .= "\"" . addcslashes(value, "\"") . "\", ";
                        }

                        let columnSql .= "(" . substr(valueSql, 0, -2) . ")";
                    } else {
                        let columnSql .= "(\"" . addcslashes(typeValues, "\"") . "\")";
                    }
                }

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Construct columns with Phalcon\Db\Column type constants (Column::TYPE_INTEGER, Column::TYPE_VARCHAR, Column::TYPE_TEXT, ...)
  2. When the type comes from dynamic input, resolve it via defined(Column::class . '::TYPE_' . $name) and fall back to a safe constant such as TYPE_TEXT
  3. For exotic types, store as TEXT/BLOB on SQLite or subclass the dialect to extend the type mapping

Example fix

// before
new Column('status', ['type' => $config['column_type']]); // raw unvalidated value

// after
use Phalcon\Db\Column;
$const = Column::class . '::TYPE_' . strtoupper((string) $config['column_type']);
$type  = defined($const) ? constant($const) : Column::TYPE_TEXT;
new Column('status', ['type' => $type]);
Defensive patterns

Strategy: validation

Validate before calling

// when the type comes from dynamic input, resolve a real constant and fall back to TEXT
$const = \Phalcon\Db\Column::class . '::TYPE_' . strtoupper((string) $config['column_type']);
$type  = defined($const) ? \constant($const) : \Phalcon\Db\Column::TYPE_TEXT;
$column = new \Phalcon\Db\Column('status', ['type' => $type]);

Type guard

function isColumnTypeConstant(int $type): bool
{
    $constants = (new \ReflectionClass(\Phalcon\Db\Column::class))->getConstants();
    return in_array($type, $constants, true);
}

Try / catch

try {
    $sql = $dialect->createTable('posts', null, $definition);
} catch (\Phalcon\Db\Exceptions\UnrecognizedDataType $e) {
    throw new InvalidArgumentException('Column type not renderable by this dialect: ' . $e->getMessage(), 0, $e);
}

Prevention

When it happens

Trigger: new Column('status', ['type' => $rawInt]) where the integer is not a Column::TYPE_* constant the SQLite dialect renders (unvalidated value from config/JSON); passing a string type name instead of a constant; column definitions shared from another dialect that hit the unmapped default branch.

Common situations: Column types read from user- or config-supplied data; casting bugs where a name like 'varchar' is used instead of Column::TYPE_VARCHAR; definitions ported from MySQL migrations that assume a wider type mapping.

Related errors


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