barryvdh/laravel-ide-helper · error · ReflectionException
Class '$class' not found.
Error message
Class '$class' not found.
What it means
Thrown by a temporary autoloader that ide-helper:meta registers while it resolves every container binding (src/Console/MetaCommand.php:188-216). Its purpose is to turn a silent autoload miss into a loud ReflectionException naming the missing class, so broken bindings surface during meta generation instead of producing an incomplete .php.meta file. It stays quiet only when the miss originates from class_exists()/interface_exists()/trait_exists()/enum_exists(), which expect a graceful return. In practice the message tells you that some class referenced by a container binding, provider, or config value cannot be autoloaded.
Source
Thrown at src/Console/MetaCommand.php:210
$autoloader = function ($class) use ($aliases) {
// ignore aliases as they're meant to be resolved elsewhere
if (in_array($class, $aliases, true)) {
return;
}
// Don't throw when class existence is being checked via class_exists(),
// interface_exists(), trait_exists(), or enum_exists(). These functions
// expect the autoloader to return gracefully when the class doesn't exist.
// Throwing here would break libraries that use class_exists() to check for
// optional dependencies (e.g. Doctrine ORM checking for removed classes).
$existsFunctions = ['class_exists', 'interface_exists', 'trait_exists', 'enum_exists'];
foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3) as $frame) {
if (isset($frame['function']) && in_array($frame['function'], $existsFunctions, true)) {
return;
}
}
throw new \ReflectionException("Class '$class' not found.");
};
spl_autoload_register($autoloader);
return $autoloader;
}
protected function getExpectedArgumentSets()
{
return [
'auth' => $this->loadTemplate('auth')->keys()->filter()->toArray(),
'configs' => $this->loadTemplate('configs')->pluck('name')->filter()->toArray(),
'middleware' => $this->loadTemplate('middleware')->keys()->filter()->toArray(),
'routes' => $this->loadTemplate('routes')->pluck('name')->filter()->toArray(),
'views' => $this->loadTemplate('views')->pluck('key')->filter()->map(function ($value) {
return (string) $value;
})->toArray(),
'translations' => $this->loadTemplate('translations')->filter()->keys()->toArray(),View on GitHub (pinned to 3a886dca5c)
Solutions
- Run `composer install` (or `composer dump-autoload -o`) so the autoloader maps every installed class, then retry `php artisan ide-helper:meta -v`.
- Re-run with -v/--verbose: the wrapping 'Cannot make ...' comment in handle() prints the abstract name together with this ReflectionException message, telling you exactly which class is missing.
- Search the codebase and config for the missing class name (config/app.php providers, bootstrap/providers.php, Auth model config, custom service providers) and remove or update the stale reference.
- If the class belongs to an optional package, either reinstall the package (`composer require vendor/pkg`) or make the binding/provider conditional on class_exists().
- If names were moved by a framework upgrade, update the imports in your own providers and re-run `composer dump-autoload`.
Example fix
# before: stale provider references a removed package class # config/app.php App\Providers\OldSmsProvider::class, # binds App\Services\Sms\Sender which no longer exists $ php artisan ide-helper:meta Class 'App\Services\Sms\Sender' not found. # after: drop the dead provider and refresh the autoloader # config/app.php # (OldSmsProvider removed) $ composer dump-autoload -o && php artisan ide-helper:meta -v
Defensive patterns
Strategy: try-catch
Validate before calling
// Preflight before ide-helper:meta: surface bindings that cannot resolve
$failures = [];
foreach (array_keys(app()->getBindings()) as $abstract) {
try {
app()->make($abstract);
} catch (\Throwable $e) {
$failures[] = $abstract . ' => ' . $e->getMessage();
}
}
if ($failures) {
fwrite(STDERR, implode("\n", $failures) . "\n");
exit(1); // fix composer autoload / stale references before generating
} Try / catch
try {
\Artisan::call('ide-helper:meta', ['--verbose' => true]);
} catch (\ReflectionException $e) {
// getMessage() names the missing class; repair vendor/config and re-run
report($e);
} Prevention
- Always run `composer install` from composer.lock before generation commands, especially in CI.
- After removing a package, re-run `composer dump-autoload -o` and grep config/app.php, bootstrap/providers.php and custom config for the removed namespace.
- Make bindings of optional packages conditional: register the provider only when class_exists() on the package class.
- Run ide-helper:meta with -v in CI so 'Cannot make ...' diagnostics are visible.
When it happens
Trigger: Running `php artisan ide-helper:meta` when a bound concrete class does not exist: composer dependencies not installed, an optimized/stale autoloader still pointing at deleted files, a service provider or config entry referencing a class from a package that was removed or renamed, or vendor code that instantiates an optional dependency without a class_exists() guard. The throw happens only when the missing class is actually used (instantiated/reflected), not merely existence-checked.
Common situations: CI or fresh clone where `composer install` was skipped or ran with --no-dev; after deleting a package while keeping its ProviderEntry in config/app.php or bootstrap/providers.php; after a major Laravel/package upgrade that moved or renamed classes while composer dump-autoload -o caches old paths; a config value (e.g. auth.model or a custom binding) pointing at a deleted model namespace.
Related errors
- Cannot generate Eloquent helper
- Your IDE helper model hook must implement Barryvdh\LaravelId
- Cannot load template for {name}: {message}
- Error resolving relation model of %s:%s() : %s
AI-assisted analysis of barryvdh/laravel-ide-helper@3a886dca5c (2026-08-23).
Data as JSON: /api/errors/053878104327b56f.
Report an issue: GitHub.