phalcon/cphalcon · error · Phalcon\Tag\Exception
Resultset returned an invalid value
Error message
Resultset returned an invalid value
What it means
While generating options from a resultset, Tag\Select::optionsFromResultset() iterates every row and reads the two 'using' fields. Each row must be an object (model or stdClass, optionally with readAttribute()) or an array. A row that is a scalar (string, int, null) cannot yield value/text, so rendering aborts with Phalcon\Tag\Exception 'Resultset returned an invalid value' (phalcon/Tag/Select.zep:283).
Source
Thrown at phalcon/Tag/Select.zep:283
let usingZero = self::toStringValue(using[0]),
usingOne = self::toStringValue(using[1]);
}
let escaper = <EscaperInterface> BaseTag::getEscaperService();
for option in iterator(resultset) {
if typeof using == "array" {
if typeof option == "object" {
if method_exists(option, "readAttribute") {
let optionValue = option->readAttribute(usingZero);
let optionText = option->readAttribute(usingOne);
} else {
let optionValue = option->{usingZero};
let optionText = option->{usingOne};
}
} else {
if unlikely typeof option != "array" {
throw new Exception(
"Resultset returned an invalid value"
);
}
let optionValue = option[usingZero];
let optionText = option[usingOne];
}
let optionValue = escaper->attributes(self::toStringValue(optionValue));
let optionText = escaper->html(self::toStringValue(optionText));
/**
* If the value is equal to the option's value we mark it as
* selected
*/
if typeof value == "array" {
if in_array(optionValue, value) {
let code .= self::echoOption(optionValue, true)View on GitHub (pinned to b7419de9cd)
Solutions
- Pass the original resultset of model objects (or array rows), not a flattened/mapped scalar list.
- Map rows to value=>text pairs and render with Tag::selectStatic(['city'], $options).
- If rows are arrays, ensure each row contains both 'using' keys; if objects, ensure the two properties are readable.
Example fix
// before
$cities = array_column($repo->all()->toArray(), 'name'); // flat list of strings
Tag::select(['city', $cities, 'using' => ['id', 'name']]); // throws
// after
$options = [];
foreach ($repo->all() as $row) {
$options[$row->id] = $row->name;
}
Tag::selectStatic(['city'], $options); Defensive patterns
Strategy: validation
Validate before calling
$rows = is_array($data) ? $data : iterator_to_array($data);
foreach ($rows as $row) {
if (!is_array($row) && !is_object($row)) {
throw new InvalidArgumentException('Select data rows must be arrays or objects');
}
} Type guard
/** @param iterable<array|object> $data */
function assertSelectData(iterable $data): void
{
foreach ($data as $row) {
if (!is_array($row) && !is_object($row)) {
throw new TypeError('Select data must contain rows, not scalars');
}
}
} Try / catch
try {
echo Tag::select(['city', $resultset, 'using' => ['id', 'name']]);
} catch (\Phalcon\Tag\Exception $e) {
$logger->warning('Falling back to empty select: ' . $e->getMessage());
echo '<select name="city"></select>';
} Prevention
- Never feed mapped/flattened scalar lists into resultset-based selects; map to value=>text pairs and use Tag::selectStatic.
- Keep hydration consistent: let Tag\Select consume model resultsets directly.
- Watch caching layers that serialize resultset rows into strings.
When it happens
Trigger: Passing a Traversable/ResultsetInterface whose iterator() yields scalars: a generator that maps rows to strings, a custom resultset of single values, a cached/serialized resultset whose rows became scalars, or an iterable of nulls.
Common situations: Selecting a single column and mapping it to a flat list before feeding Tag::select; wrapping a resultset in a caching layer that flattens rows; array_column() output passed as data with a resultset-typed option; hydration modes that produce scalars.
Related errors
- Parameter 'using' requires two values
- The 'using' parameter requires exactly two values
- Resultset returned an invalid value
- The 'using' parameter is required
- The 'using' parameter should be an array
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/d839bf308202ffaf.
Report an issue: GitHub.