cakephp/cakephp · error · InvalidArgumentException

Passing extra expressions by associative array

Error message

Passing extra expressions by associative array (`'%s' => '%s'`) is not allowed to avoid potential SQL injection. Use QueryExpression or numeric array instead.

What it means

OrderByExpression rejects associative arrays where both key and value are strings and the value is not ASC/DESC, because generating `ORDER BY key value` from arbitrary string pairs could inject SQL. Only explicit QueryExpression objects or numeric arrays of expressions are allowed for complex ordering.

Solutions

  1. Use an expression: ->orderBy($query->newExpr('FIELD(name)')) or a QueryExpression
  2. Use 'ASC'/'DESC' as the value if that was the intent
  3. Build ordering from a numeric array of expression objects instead of a string-keyed map

Example fix

// before
$query->orderBy(['name' => 'LOWER(name)']);
// after
$query->orderBy([$query->newExpr('LOWER(name)')]);
Defensive patterns

Strategy: validation

Validate before calling

foreach ($order as $k => $v) { if (is_string($k) && is_string($v) && !in_array(strtoupper($v), ['ASC','DESC'], true)) { throw new \InvalidArgumentException('Use an expression for custom ordering'); } }

Type guard

function isValidOrderValue(mixed $v): bool { return is_string($v) && in_array(strtoupper($v), ['ASC','DESC'], true); }

Try / catch

try { $query->sql(); } catch (\InvalidArgumentException $e) { if (str_contains($e->getMessage(), 'Passing extra expressions')) { /* rebuild order with expressions */ } }

Prevention

When it happens

Trigger: Calling ->orderBy(['field' => 'some_function(other)']) or ->order(['name' => 'custom sql']) with a non-ASC/DESC string value.

Common situations: Migrating old code that relied on ordering by raw SQL snippets in associative arrays; users passing dynamic sort definitions from request input; version upgrades (CakePHP 4.3+/5) that hardened this API.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of cakephp/cakephp@1128eba9b0 (2026-09-12). Data as JSON: /api/errors/54d2c3a544447e8a. Report an issue: GitHub.

Appendix: source

Thrown at src/Database/Expression/OrderByExpression.php:78

    /**
     * Auxiliary function used for decomposing a nested array of conditions and
     * building a tree structure inside this object to represent the full SQL expression.
     *
     * New order by expressions are merged to existing ones
     *
     * @param array $conditions list of order by expressions
     * @param array $types list of types associated on fields referenced in $conditions
     * @return void
     */
    protected function _addConditions(array $conditions, array $types): void
    {
        foreach ($conditions as $key => $val) {
            if (
                is_string($key) &&
                is_string($val) &&
                !in_array(strtoupper($val), ['ASC', 'DESC'], true)
            ) {
                throw new InvalidArgumentException(
                    sprintf(
                        "Passing extra expressions by associative array (`'%s' => '%s'`) " .
                        'is not allowed to avoid potential SQL injection. ' .
                        'Use QueryExpression or numeric array instead.',
                        $key,
                        $val,
                    ),
                );
            }
        }

        $this->_conditions = array_merge($this->_conditions, $conditions);
    }
}

View on GitHub (pinned to 1128eba9b0)