phalcon/cphalcon · error · Phalcon\Db\Exceptions\InvalidWhereConditions
Invalid WHERE clause conditions
Error message
Invalid WHERE clause conditions
What it means
In update(), $whereCondition must be a string (appended raw to the UPDATE SQL, unescaped) or an array (with optional 'conditions', 'bind', 'bindTypes' keys). Any other type throws InvalidWhereConditions. Note that Zephir's typeof check rejects objects with __toString() too — a Stringable object is not a 'string' at this level, so it must be cast first.
Source
Thrown at phalcon/Db/Adapter/AbstractAdapter.zep:1455
let escapedTable = this->escapeIdentifier(tableName),
setClause = join(", ", placeholders);
if whereCondition !== null {
let updateSql = "UPDATE " . escapedTable . " SET " . setClause . " WHERE ";
/**
* String conditions are simply appended to the SQL
*/
if typeof whereCondition == "string" {
let updateSql .= whereCondition;
} else {
/**
* Array conditions may have bound params and bound types
*/
if unlikely typeof whereCondition != "array" {
throw new InvalidWhereConditions();
}
/**
* If an index 'conditions' is present it contains string where
* conditions that are appended to the UPDATE SQL
*/
if fetch conditions, whereCondition["conditions"] {
let updateSql .= conditions;
}
/**
* Bound parameters are arbitrary values that are passed
* separately
*/
if fetch whereBind, whereCondition["bind"] {
merge_append(updateValues, whereBind);
}
View on GitHub (pinned to b7419de9cd)
Solutions
- Pass the condition as a string: "id = 123" (remember: not escaped — bind when values are dynamic)
- Or use the array form for safe binding: ['conditions' => 'id = ?', 'bind' => [$id], 'bindTypes' => [Column::BIND_PARAM_INT]]
- Cast Stringable objects: $where = (string) $exprObject before passing
Example fix
// before
$db->update('users', $fields, $values, $someConditionObject);
// after
$db->update('users', $fields, $values, [
'conditions' => 'id = ?',
'bind' => [$id],
'bindTypes' => [Column::BIND_PARAM_INT],
]); Defensive patterns
Strategy: validation
Validate before calling
if ($whereCondition !== null && !is_string($whereCondition) && !is_array($whereCondition)) {
$whereCondition = is_object($whereCondition) && method_exists($whereCondition, '__toString')
? (string) $whereCondition
: throw new InvalidArgumentException('whereCondition must be string or array');
}
$connection->update($table, $fields, $values, $whereCondition); Prevention
- Use the array form ['conditions' => ..., 'bind' => ..., 'bindTypes' => ...] whenever the condition includes user data — it binds safely
- Cast Stringable objects to string before passing; the internal typeof check does not honor __toString()
- Static-analyze call sites of update() for the 4th argument type
When it happens
Trigger: $db->update('users', $fields, $values, 123); passing an object such as a PDOStatement, an expression builder result, or a value object with __toString(); passing null is fine (default) but false/float/int throw.
Common situations: Passing a where clause built by another library (query builder object) directly; Stringable enums/value objects used as conditions; truthy scalar conditions coming from untyped request data.
Related errors
- The number of values in the update is not the same as fields
- Incomplete number of bind types
- Invalid bind parameter (1)
- The 'dialectClass' '{className}' must implement Phalcon\Db\D
- Savepoints are not supported by this database adapter
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/c9f2d5a25bd6ea35.
Report an issue: GitHub.