MissingView
Emitted when a view name passed to any of the following does not correspond to an existing Blade template on disk:
view()helper,Factory::make()/first()/renderWhen()/renderUnless()/renderEach()/composer()/creator(), and theirViewfacade forms (concrete, contract-typed, and aliases)ResponseFactory::view()(response()->view(),Illuminate\Contracts\Routing\ResponseFactory, and theResponsefacade)Router::view()and theRoutefacadeIlluminate\Notifications\Messages\MailMessage::view()/markdown()/text(), including the array form ofview()Illuminate\Mail\Mailable::view()/markdown()/text()Illuminate\Mail\Mailables\Content’sview,html,text, andmarkdownconstructor argumentsIlluminate\Testing\TestResponse::assertViewIs()Illuminate\Foundation\Testing\Concerns\InteractsWithViews::view()
Why this is a problem
If the referenced view file doesn’t exist, Laravel throws an InvalidArgumentException at runtime. This check catches typos and missing templates during static analysis.
Examples
// Bad — typo in the view name
view('emails.welcom'); // MissingView
// Good — the view file exists
view('emails.welcome');
// Bad — referencing a deleted template
view('admin.old-dashboard'); // MissingView
// Good
view('admin.dashboard');
How to fix
- Check that the Blade file exists at the expected path (e.g.,
resources/views/emails/welcome.blade.php) - Fix any typos in the view name
- If the view is provided by a package, use the namespaced syntax (e.g.,
view('package::view.name')) — namespaced views are not checked by this rule
Configuration
This check is enabled by default. Reported at error levels 1 to 4 (like Psalm’s UndefinedMagicMethod), info at looser levels. Disable it in your psalm.xml:
<plugins>
<pluginClass class="Psalm\LaravelPlugin\Plugin">
<findMissingViews value="false" />
</pluginClass>
</plugins>
Limitations
- Only string literal view names are checked — dynamic or concatenated names are skipped
- Namespaced views (e.g.,
mail::html.header) are skipped - Only
.blade.phpand.phpextensions are checked - Only view paths known at boot time are searched (
config('view.paths')plus paths added by service providers) Factory::first()andResponseFactory::view()’s array form only flag the call when every candidate is a literal AND all of them are missing. A non-literal candidate anywhere in the list, or one that resolves, skips the checkrenderEach()’s$emptyargument is skipped when it starts withraw|(Laravel treats that as raw text, not a view name)Factory::composer()/creator()wildcard patterns are skipped because they are event patterns, not concrete template namesMailMessage::view()’s array form is only checked for a literal array with literal keys, and followsMailer::parseView(): when key0is set (non-null), keys0and1are checked; otherwisehtmlandtext.raw(raw text, not a view name) is skipped. The array is skipped if key0may be null, is an unbounded template or otherwise not proven non-null, or if any key is a negative integer (implicit indexes after it differ between PHP 8.2 and 8.3+)