phalcon/cphalcon · error · InvalidOrderByExpression
Invalid SQL-ORDER-BY expression
Error message
Invalid SQL-ORDER-BY expression
What it means
getSqlExpressionOrderBy() throws InvalidOrderByExpression when the orderBy definition is an array but one of its elements is not an array. Each element must be a two-part array: [expression, 'ASC'|'DESC'], where the first slot is itself a resolvable expression array. A plain string like 'name DESC' inside the array is rejected at this layer.
Source
Thrown at phalcon/Db/Dialect.zep:1330
* Resolve an ORDER BY clause
*
* @param array|string expression
* @param string|null escapeChar
* @param array bindCounts
*
* @return string
*/
final protected function getSqlExpressionOrderBy(var expression, string escapeChar = null, array bindCounts = []) -> string
{
var field, fields, type, fieldSql = null;
if typeof expression === "array" {
let fields = [];
for field in expression {
if unlikely typeof field != "array" {
throw new InvalidOrderByExpression();
}
let fieldSql = this->getSqlExpression(
field[0],
escapeChar,
bindCounts
);
/**
* In the numeric 1 position could be a ASC/DESC clause
*/
if fetch type, field[1] && type != "" {
let fieldSql .= " " . type;
}
let fields[] = fieldSql;
}
View on GitHub (pinned to b7419de9cd)
Solutions
- Convert each entry to [expression, direction] form: [['type' => 'raw', 'value' => 'name'], 'DESC']
- Let Phalcon\Db\QueryBuilder->orderBy('name DESC') do the string parsing for you
- Sanitize user-supplied sort input into [field, direction] pairs and whitelist the direction
Example fix
// before
$definition['orderBy'] = ['name DESC', 'id'];
// after
$definition['orderBy'] = [
[['type' => 'raw', 'value' => 'name'], 'DESC'],
[['type' => 'raw', 'value' => 'id'], 'ASC'],
]; Defensive patterns
Strategy: validation
Validate before calling
foreach ($definition['orderBy'] ?? [] as $entry) {
if (!is_array($entry)) {
throw new InvalidArgumentException('Each ORDER BY entry must be [expr, direction]');
}
} Type guard
function isOrderByExpressionList(array $orderBy): bool
{
foreach ($orderBy as $entry) {
if (!is_array($entry)) {
return false;
}
}
return true;
} Try / catch
try {
$sql = $dialect->select($definition);
} catch (\Phalcon\Db\Exceptions\InvalidOrderByExpression $e) {
throw new InvalidArgumentException('Malformed ORDER BY definition', 0, $e);
} Prevention
- Parse sort strings once into [expression, ASC|DESC] pairs and whitelist the direction
- Use Query Builder->orderBy('name DESC') for string input
- Never forward user sort input raw into a dialect definition
When it happens
Trigger: Passing definition['orderBy'] = ['name DESC'] or ['id'] (strings) directly to Dialect::select(); mixing string and array entries in the orderBy array. The Query Builder parses orderBy strings into [expr, direction] pairs before reaching the dialect, so this fires mainly on hand-built definitions.
Common situations: Forwarding raw user sort parameters straight into a select() definition; porting SQL ORDER BY clause strings into the array-based API; inconsistent data shape between code paths that build orderBy.
Related errors
- Invalid SQL-GROUP-BY expression
- Invalid SQL-list expression
- Invalid SQL-unary expression
- The index 'tables' is required in the definition array
- The index 'columns' is required in the definition array
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/1b437ff518a633fa.
Report an issue: GitHub.