phalcon/cphalcon · error · Phalcon\Mvc\Model\Exceptions\IndexNotInRow

The index does not exist in the row

Error message

The index does not exist in the row

What it means

Phalcon\Mvc\Model\Row is the read-only result object the ORM returns for queries that select partial columns or computed expressions (e.g. via ModelsManager::createQuery with a column list). It implements ArrayAccess, and offsetGet() throws IndexNotInRow when the requested key is not a property on the row - i.e. the key was never selected or aliased into the result set. Only the exact column names/aliases present in the SELECT are addressable.

Source

Thrown at phalcon/Mvc/Model/Row.zep:56

     *
     * @param string|int $index
     */
    public function offsetExists(mixed index) -> bool
    {
        return property_exists(this, index);
    }

    /**
     * Gets a record in a specific position of the row
     *
     * @param string|int index
     *
     * @return string|ModelInterface
     */
    public function offsetGet(mixed index) -> mixed
    {
        if !property_exists(this, index) {
            throw new IndexNotInRow();
        }

        return this->{index};
    }

    /**
     * Rows cannot be changed. It has only been implemented to meet the definition of the ArrayAccess interface
     *
     * @param string|int offsetSet
     * @param ModelInterface value
     */
    public function offsetSet(mixed offset, mixed value) -> void
    {
        throw new RowIsImmutable();
    }

    /**
     * Rows cannot be changed. It has only been implemented to meet the definition of the ArrayAccess interface

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Add the missing column (or an alias for it) to the SELECT clause of the query producing the Row
  2. Guard the access with property_exists($row, 'key') or isset($row['key']) before reading
  3. If you need full model behavior, select the model itself (SELECT * FROM Model or select the entity) instead of bare columns so you get a Model instance rather than Row
  4. Dump the available keys once (get_object_vars($row) or iterator_to_array($row)) to see exactly what the row contains and fix the key name

Example fix

// before
$title = $row['inv_title'];
$price = $row['inv_price']; // throws IndexNotInRow - not selected

// after: select it, or guard it
$queries = $modelsManager->createQuery(
    'SELECT inv_title, inv_price FROM Invoices WHERE inv_id = :id:'
);
// ...
$price = property_exists($row, 'inv_price') ? $row['inv_price'] : null;
Defensive patterns

Strategy: validation

Validate before calling

// Before reading a key off a partial-select result row
use Phalcon\Mvc\Model\Row;

function rowValue(Row $row, string $key, mixed $default = null): mixed
{
    return property_exists($row, $key) ? $row->{$key} : $default;
}

$price = rowValue($row, 'inv_price');

Type guard

function rowHas(Row $row, string $key): bool
{
    return property_exists($row, $key);
}

Try / catch

try {
    $value = $row['inv_price'];
} catch (\Phalcon\Mvc\Model\Exceptions\IndexNotInRow $e) {
    $value = null; // or log which key was missing: inspect get_object_vars($row)
}

Prevention

When it happens

Trigger: Calling $row['key'] (or $row->readAttribute('key')) on a Row where 'key' was not part of the SELECT clause; using a typo'd or case-mismatched alias (aliases are case-sensitive); accessing a column after renaming it in the DB without updating the query; calling $row['id'] on a raw/phalcon-db result row forwarded through Model::Row.

Common situations: Partial SELECT queries ('SELECT inv_title FROM ...') followed by code that reads other model attributes; queries with expression aliases where code uses the raw column name instead of the alias; switching hydration from Models to Row objects during refactoring; joins where the developer assumes all table columns exist on the row.

Related errors


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