laravel/framework · error · InvalidArgumentException
Unable to find observer
Error message
Unable to find observer: {$class} What it means
Thrown by resolveObserverClassName() when the value passed to an observer registration (e.g. Model::observe($class)) is a string that does not correspond to an existing class. The method resolves objects to their class, accepts existing class strings, and rejects anything class_exists() cannot find.
Solutions
- Create the observer class at the given FQCN with the correct namespace and filename.
- Verify the namespace and class name match exactly; run composer dump-autoload.
- Pass the observer class constant (UserObserver::class) instead of a string to avoid typos.
- Confirm the observer is registered in AppServiceProvider (or a dedicated provider) only after the class exists.
Example fix
// before
User::observe('App\Observers\UserObserver'); // class does not exist
// after
// 1) create app/Observers/UserObserver.php with namespace App\Observers;
User::observe(App\Observers\UserObserver::class); Defensive patterns
Strategy: validation
Validate before calling
$observerClass = App\Observers\UserObserver::class;
if (! class_exists($observerClass)) {
throw new \LogicException("Observer {$observerClass} does not exist; run composer dump-autoload or create the class.");
}
User::observe($observerClass); Type guard
function observerClassExists(string $class): bool
{
return class_exists($class);
} Prevention
- Pass the observer's ::class constant rather than a literal string to catch typos early.
- Create the observer file before registering it in the service provider.
- Run composer dump-autoload after adding observer files.
When it happens
Trigger: Calling User::observe('App\Observers\UserObserver') where App\Observers\UserObserver does not exist (not defined, wrong namespace, or not autoloaded). Also passing a misspelled or fully-qualified-but-wrong class string.
Common situations: Registering observers in a service provider with a class string that was renamed or never created; the observer file exists but the namespace/filename mismatch prevents autoloading; copy-pasting an observe() call from another model without adjusting the class; missing composer dump-autoload after adding the file.
Related errors
- Call to undefined cast
- Could not verify the hashed value's configuration.
- Expected class to implement guessResourceName method. Make…
- Failed to find resource class for model
- Failed to find resource class for model
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/b75ceef18527e0b8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Illuminate/Database/Eloquent/Concerns/HasEvents.php:123
/**
* Resolve the observer's class name from an object or string.
*
* @param object|string $class
* @return class-string
*
* @throws \InvalidArgumentException
*/
private function resolveObserverClassName($class)
{
if (is_object($class)) {
return get_class($class);
}
if (class_exists($class)) {
return $class;
}
throw new InvalidArgumentException('Unable to find observer: '.$class);
}
/**
* Get the observable event names.
*
* @return string[]
*/
public function getObservableEvents()
{
return array_merge(
[
'retrieved', 'creating', 'created', 'updating', 'updated',
'saving', 'saved', 'restoring', 'restored', 'replicating',
'trashed', 'deleting', 'deleted', 'forceDeleting', 'forceDeleted',
],
$this->observables
);
}View on GitHub (pinned to e0f6eb3518)