phalcon/cphalcon · error · InvalidListExpression

Invalid SQL-list expression

Error message

Invalid SQL-list expression

What it means

getSqlExpressionList() throws InvalidListExpression when a 'list'-type expression cannot be resolved: it requires either a numeric element 0 or a 'value' key holding an array of items. If neither key exists, or the fetched value is not an array (e.g. a string or null), the expression is not a valid list and the compiler throws instead of emitting broken SQL.

Source

Thrown at phalcon/Db/Dialect.zep:1284

        if isset expression["separator"] {
            let separator = expression["separator"];
        }

        if (fetch values, expression[0] || fetch values, expression["value"]) && typeof values == "array" {

            for item in values {
                let items[] = this->getSqlExpression(item, escapeChar, bindCounts);
            }

            if isset expression["parentheses"] && expression["parentheses"] === false {
                return join(separator, items);
            }

            return "(" . join(separator, items) . ")";
        }

        throw new InvalidListExpression();
    }

    /**
     * Resolve object expressions
     *
     * @param array expression
     * @param string|null escapeChar
     * @param array bindCounts
     *
     * @return string
     */
    final protected function getSqlExpressionObject( array expression, string escapeChar = null,  array bindCounts = []) -> string
    {
        var domain = null, objectExpression;

        let objectExpression = [
            "type": "all"
        ];

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Give the list expression an array payload: ['type' => 'list', 'value' => [1, 2, 3]] or the numeric form [ ['type' => 'list'], [1, 2, 3] ]
  2. Normalize before compiling: if (isset($expr['type']) && $expr['type'] === 'list') { $expr['value'] = (array) ($expr['value'] ?? []); }
  3. For IN clauses prefer the Query Builder / PHQL IN operator which produces correct list expressions

Example fix

// before
$expr = ['type' => 'list', 'value' => '1,2,3'];

// after
$expr = ['type' => 'list', 'value' => [1, 2, 3]];
Defensive patterns

Strategy: validation

Validate before calling

if (($expr['type'] ?? null) === 'list') {
    $values = $expr[0] ?? $expr['value'] ?? null;
    if (!is_array($values)) {
        throw new InvalidArgumentException('List expression requires an array payload under "value"');
    }
}

Type guard

function isValidListExpression(array $expr): bool
{
    if (($expr['type'] ?? null) !== 'list') {
        return true; // not a list, nothing to check here
    }
    $values = $expr[0] ?? $expr['value'] ?? null;
    return is_array($values);
}

Try / catch

try {
    $sql = $dialect->select($definition);
} catch (\Phalcon\Db\Exceptions\InvalidListExpression $e) {
    throw new InvalidArgumentException('List expression missing array payload', 0, $e);
}

Prevention

When it happens

Trigger: Passing ['type' => 'list', 'value' => '1,2,3'] (string instead of array); a list expression with items stored under a different key ('values', 'items'); an empty/aliased array where fetch of both expression[0] and expression['value'] fails; nested expression data built by your own query layer that forgets the 'value' key.

Common situations: Custom IN() expression builders; deserializing expression arrays from JSON where the list payload got flattened; upgrading from code that constructed list expressions ad hoc against an older dialect.

Related errors


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