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

Incomplete number of bind types

Error message

Incomplete number of bind types

What it means

buildValuePlaceholder() (used by insert() and update()) throws IncompleteBindTypes ('Incomplete number of bind types') when $dataTypes is an array but has no entry at a given position. If you supply a types array at all, it must cover every value position with numeric keys 0..n-1; a partial or name-keyed map leaves a position unfetched and fails.

Source

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

            let value = (string) value;
        }

        if value === null {
            return [
                "placeholder" : "null",
                "bind"        : false,
                "value"       : null,
                "hasBindType" : false,
                "bindType"    : null
            ];
        }

        let bindType    = null,
            hasBindType = (typeof dataTypes == "array");

        if hasBindType {
            if unlikely !fetch bindType, dataTypes[position] {
                throw new IncompleteBindTypes();
            }
        }

        return [
            "placeholder" : "?",
            "bind"        : true,
            "value"       : value,
            "hasBindType" : hasBindType,
            "bindType"    : bindType
        ];
    }
}

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Make dataTypes a positional array covering every value: one entry per value, keys 0..n-1, same order as values
  2. If you do not need explicit typing, pass null (or omit) instead of an incomplete array
  3. Derive both arrays from one structure: $pairs = [...]; insert($table, array_values($pairs), null, array_values($typeMap)) with count($typeMap) === count($pairs)

Example fix

// before
$db->insert('users', ['John', 25], null, [Column::BIND_PARAM_STR]); // 2 values, 1 type

// after
$db->insert('users', ['John', 25], null, [
    Column::BIND_PARAM_STR,
    Column::BIND_PARAM_INT,
]);
Defensive patterns

Strategy: validation

Validate before calling

if (is_array($dataTypes) && count($dataTypes) < count($values)) {
    throw new InvalidArgumentException(
        sprintf('dataTypes has %d entries for %d values', count($dataTypes), count($values))
    );
}
$connection->insert($table, $values, $fields, $dataTypes);

Prevention

When it happens

Trigger: $db->insert('users', ['John', 25], null, [Column::BIND_PARAM_STR]) — one type for two values; dataTypes built as ['name' => BIND_PARAM_STR] (field-name keys) while lookup is by numeric position; dataTypes shorter than values after array_filter.

Common situations: Type maps authored per-column-name (natural for humans) but consumed positionally; reusing an insert type array for a subset of fields; appending values without updating the parallel types array.

Related errors


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