laravel/framework · error · MissingAttributeException

The attribute [ ] either does not exist or was not…

Error message

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

What it means

Thrown as MissingAttributeException when Model::preventAccessingMissingAttributes() has been enabled (strict mode) and code reads an attribute that was not selected from the database and is not a relation. The guard fires for existing, non-freshly-created models so that accidental access to columns not in the SELECT list surfaces as an error rather than silently returning null. A custom violation callback can be registered to intercept it instead of throwing.

Solutions

  1. Add the missing column to the SELECT list (select('id', 'email') or ->addSelect('email')).
  2. Disable strict access selectively with Model::preventAccessingMissingAttributes(false) for the offending scope.
  3. Register a Model::handleMissingAttributeViolationUsing(fn (...) => ...) callback to log instead of throw.
  4. Confirm the column exists in the table schema and the model's $attributes/$casts are consistent.

Example fix

// before
Model::preventAccessingMissingAttributes(true);
$user = User::select('id')->first();
echo $user->email; // MissingAttributeException

// after
$user = User::select('id', 'email')->first();
echo $user->email;
Defensive patterns

Strategy: validation

Validate before calling

// Before reading an attribute that may be missing:
$selected = ['id', 'name'];
if (! in_array('email', $selected, true)) {
    $selected[] = 'email';
}
$user = User::select($selected)->first();
$explicit = $user->getAttributes();
$ok = array_key_exists('email', $explicit);

Type guard

function attributeWasRetrieved(\Illuminate\Database\Eloquent\Model $model, string $key): bool
{
    return array_key_exists($key, $model->getAttributes());
}

Try / catch

try {
    return $model->{$key};
} catch (\Illuminate\Database\Eloquent\MissingAttributeException $e) {
    report($e);
    return null;
}

Prevention

When it happens

Trigger: Calling User::select('id')->first()->email when 'email' was not selected; calling $model->some_column after a query that excluded it; accessing an attribute on a model hydrated from a partial SELECT or from raw DB values that omit the column. Only triggers when strict attribute access prevention is turned on.

Common situations: Enabling Model::shouldBeStrict() or preventAccessingMissingAttributes() in testing/non-production and then hitting a query that uses select() or addSelect() with a subset of columns; legacy code that accessed attributes which were later removed from a migration; aggregate/analytic queries that select computed columns only.

Related errors


AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11). Data as JSON: /api/errors/502138c175110d3f. Report an issue: GitHub.

Appendix: 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 e0f6eb3518)