laravel/framework · error · MissingAttributeException

The attribute [%s] either does not exist or was not retrieve

Error message

The attribute [%s] either does not exist or was not retrieved for model [%s].

What it means

When Model::preventAccessingMissingAttributes() is enabled (strict mode), accessing an attribute that is neither in the attributes array nor a relation/relation-resolver raises MissingAttributeException. This catches silent null returns caused by SELECTing a subset of columns while accessing unselected attributes.

Source

Thrown at src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:527

    /**
     * Either throw a missing attribute exception or return null depending on Eloquent's configuration.
     *
     * @param  string  $key
     * @return null
     *
     * @throws \Illuminate\Database\Eloquent\MissingAttributeException
     */
    protected function throwMissingAttributeExceptionIfApplicable($key)
    {
        if ($this->exists &&
            ! $this->wasRecentlyCreated &&
            static::preventsAccessingMissingAttributes()) {
            if (isset(static::$missingAttributeViolationCallback)) {
                return call_user_func(static::$missingAttributeViolationCallback, $this, $key);
            }

            throw new MissingAttributeException($this, $key);
        }

        return null;
    }

    /**
     * Get a plain attribute (not a relationship).
     *
     * @param  string  $key
     * @return mixed
     */
    public function getAttributeValue($key)
    {
        return $this->transformModelValue($key, $this->getAttributeFromArray($key));
    }

    /**
     * Get an attribute from the $attributes array.

View on GitHub (pinned to bd6b5437e6)

Solutions

  1. Add the missing column to the query: ->select('id', 'title') or ->addSelect('title').
  2. Use ->withColumns() / ensure full row hydration by removing over-restrictive select().
  3. Confirm the attribute name spelling and that the column exists in the table/migration.

Example fix

// before
Model::preventAccessingMissingAttributes(true);
$post = Post::select('id')->first();
echo $post->title; // throws

// after
$post = Post::select('id', 'title')->first();
echo $post->title;
Defensive patterns

Strategy: validation

Validate before calling

// Before strict access, ensure columns are present
$cols = ['id', 'title']; // required
$row = Post::select($cols)->first();
foreach ($cols as $c) {
    if (! array_key_exists($c, $row->getAttributes())) {
        throw new \RuntimeException("Column {$c} not selected");
    }
}

Type guard

function hasAttributeSelected(\Illuminate\Database\Eloquent\Model $m, string $key): bool
{
    return array_key_exists($key, $m->getAttributes())
        || $m->hasGetMutator($key)
        || $m->hasCast($key);
}

Try / catch

try {
    return $model->{$key};
} catch (\Illuminate\Database\Eloquent\MissingAttributeException $e) {
    report("Missing attribute {$key} on ".get_class($model));
    return null;
}

Prevention

When it happens

Trigger: Enabling strict attribute access (often in tests via Model::preventAccessingMissingAttributes(true)) then doing SomeModel::select('id')->first()->title, where 'title' was not in the SELECT list. Also fires for genuinely misspelled attribute names.

Common situations: Strict-mode enabled globally in TestCase; using select() or addSelect() that omits a column later read by a view/serializer; column renamed in migration but code not updated; using ->only([...]) with a fresh model.

Related errors


AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06). Data as JSON: /data/errors/502138c175110d3f.json. Report an issue: GitHub.