Describe the bug
BlazeRuntime::ensureCompiled() uses an in-memory $this->compiled array to skip re-compilation within the same request. However, if compiled view files are deleted mid-request (e.g. via Artisan::call('optimize:clear')), subsequent calls to ensureCompiled() return early based on the stale in-memory cache — without verifying the file still exists on disk. The following require_once then fails with "No such file or directory".
The issue occurs reliably when a Livewire component action triggers cache clearing (e.g. toggling a module that calls optimize:clear) and the component re-renders in the same request.
Component causing the issue
Any Blaze-compiled component used inside a view that re-renders after optimize:clear is called within the same request. In my case, <flux:switch> inside a module settings page:
@foreach($modules as $module)
@if($module['is_protected'])
<flux:switch disabled :checked="$module['is_enabled']" />
@else
<flux:switch wire:click="toggleModule('{{ $module['name'] }}')" :checked="$module['is_enabled']" />
@endif
@endforeach
The toggleModule action calls Artisan::call('optimize:clear') which deletes all compiled views, then Livewire re-renders the component in the same request.
Expected behavior
After compiled views are cleared mid-request, ensureCompiled() should detect the missing file and recompile it before require_once executes.
Actual behavior
ensureCompiled() returns immediately at line 48-50 because $this->compiled[$path] is still set from the first render. The compiled file no longer exists on disk, so the require_once on the next line fails:
require_once(.../storage/framework/views/ad784b2e43740a3a648880f501461253.php):
Failed to open stream: No such file or directory
Root cause
In BlazeRuntime::ensureCompiled() (line 46-59):
public function ensureCompiled(string $path, string $compiledPath): void
{
if (isset($this->compiled[$path])) {
return; // ← Returns early even if file was deleted
}
$this->compiled[$path] = true;
if (file_exists($compiledPath) && filemtime($path) <= filemtime($compiledPath)) {
return;
}
$this->compiler->compile($path);
}
The $this->compiled guard at line 48 does not verify the compiled file still exists. Once a path is marked as "compiled" during the first render, all subsequent calls skip compilation entirely — even if optimize:clear has deleted the files in between.
Suggested fix
Add a file_exists() check to the in-memory cache guard:
public function ensureCompiled(string $path, string $compiledPath): void
{
if (isset($this->compiled[$path]) && file_exists($compiledPath)) {
return;
}
$this->compiled[$path] = true;
if (file_exists($compiledPath) && filemtime($path) <= filemtime($compiledPath)) {
return;
}
$this->compiler->compile($path);
}
This preserves the performance benefit of the in-memory cache (avoiding redundant filemtime calls) while correctly handling the case where files are deleted mid-request.
Steps to reproduce
- Create a Livewire component that renders a Blaze-compiled view (e.g. any view using
<flux:*> components)
- Add an action to the component that calls
Artisan::call('optimize:clear') (or view:clear)
- After the action, the component re-renders in the same request
- The re-render fails with
require_once ... Failed to open stream: No such file or directory
Minimal test case:
// In a Livewire component
public function clearAndRerender(): void
{
Artisan::call('optimize:clear');
// Component re-renders after this → crash
}
Environment
- Laravel version: 12.53.0
- PHP version: 8.4.18
- Blaze version: 1.0.3
Additional context
This bug surfaces consistently in test suites (both --parallel and sequential) because:
- Tests start with a clean view cache
- First render compiles views and populates
$this->compiled
- A Livewire action triggers
optimize:clear (e.g. module toggle, settings save)
- Same test re-renders the component →
require_once fails
My current workaround is extending BlazeRuntime and overriding ensureCompiled() with the fix above, then rebinding in AppServiceProvider::register():
$this->app->singleton(BlazeRuntime::class, FixedBlazeRuntime::class);
Describe the bug
BlazeRuntime::ensureCompiled()uses an in-memory$this->compiledarray to skip re-compilation within the same request. However, if compiled view files are deleted mid-request (e.g. viaArtisan::call('optimize:clear')), subsequent calls toensureCompiled()return early based on the stale in-memory cache — without verifying the file still exists on disk. The followingrequire_oncethen fails with "No such file or directory".The issue occurs reliably when a Livewire component action triggers cache clearing (e.g. toggling a module that calls
optimize:clear) and the component re-renders in the same request.Component causing the issue
Any Blaze-compiled component used inside a view that re-renders after
optimize:clearis called within the same request. In my case,<flux:switch>inside a module settings page:The
toggleModuleaction callsArtisan::call('optimize:clear')which deletes all compiled views, then Livewire re-renders the component in the same request.Expected behavior
After compiled views are cleared mid-request,
ensureCompiled()should detect the missing file and recompile it beforerequire_onceexecutes.Actual behavior
ensureCompiled()returns immediately at line 48-50 because$this->compiled[$path]is still set from the first render. The compiled file no longer exists on disk, so therequire_onceon the next line fails:Root cause
In
BlazeRuntime::ensureCompiled()(line 46-59):The
$this->compiledguard at line 48 does not verify the compiled file still exists. Once a path is marked as "compiled" during the first render, all subsequent calls skip compilation entirely — even ifoptimize:clearhas deleted the files in between.Suggested fix
Add a
file_exists()check to the in-memory cache guard:This preserves the performance benefit of the in-memory cache (avoiding redundant
filemtimecalls) while correctly handling the case where files are deleted mid-request.Steps to reproduce
<flux:*>components)Artisan::call('optimize:clear')(orview:clear)require_once ... Failed to open stream: No such file or directoryMinimal test case:
Environment
Additional context
This bug surfaces consistently in test suites (both
--paralleland sequential) because:$this->compiledoptimize:clear(e.g. module toggle, settings save)require_oncefailsMy current workaround is extending
BlazeRuntimeand overridingensureCompiled()with the fix above, then rebinding inAppServiceProvider::register():