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

Unable to insert into {table} without data

Error message

Unable to insert into {table} without data

What it means

insert() requires a non-empty $values array ('if unlikely empty values' throws CannotInsertWithoutData). An INSERT with zero values cannot be generated (there would be no columns and no placeholders), so the adapter refuses immediately, before any SQL is built.

Source

Thrown at phalcon/Db/Adapter/AbstractAdapter.zep:935

     *     ["Test Invoice", 100],
     *     ["inv_title", "inv_total"]
     * );
     *
     * // Next SQL sentence is sent to the database system
     * INSERT INTO `co_invoices` (`inv_title`, `inv_total`) VALUES ("Test Invoice", 100);
     * ```
     */
    public function insert(string table,  array values, var fields = null, var dataTypes = null) -> bool
    {
        var bindDataTypes, escapedTable, escapedFields, field,
            insertSql, insertValues, joinedValues, placeholder, placeholders,
            position, tableName, value;

        /**
         * A valid array with more than one element is required
         */
        if unlikely empty values {
            throw new CannotInsertWithoutData(table);
        }

        let placeholders  = [],
            insertValues  = [],
            bindDataTypes = [];

        /**
         * Objects are casted using __toString, null values are converted to
         * string "null", everything else is passed as "?"
         */
        for position, value in values {
            let placeholder = this->buildValuePlaceholder(value, position, dataTypes);

            let placeholders[] = placeholder["placeholder"];

            if placeholder["bind"] {
                let insertValues[] = placeholder["value"];

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Guard before calling: if (!empty($values)) { $db->insert(...); }
  2. If the empty payload is a bug upstream, fix the source that produced it rather than skipping
  3. For optional inserts, decide explicitly: skip silently or raise your own validation error to the caller

Example fix

// before
$db->insert('users', $filtered); // $filtered = [] after whitelist filtering

// after
if (!empty($filtered)) {
    $db->insert('users', $filtered);
}
Defensive patterns

Strategy: validation

Validate before calling

if (empty($values)) {
    // nothing to insert — skip or surface a domain error
    return;
}
$connection->insert($table, $values, $fields, $dataTypes);

Prevention

When it happens

Trigger: $db->insert('users', []) — typically because the payload was built from a filtered request, a loop over an empty collection, or array_filter() removing every element; also array_map over an empty source list.

Common situations: Mass-assignment code where all keys are stripped by a whitelist filter; batch insert loops where one chunk is empty; form handlers that insert on POST bodies with no relevant fields; CSV/import pipelines hitting an empty record.

Related errors


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