Description
On Livewire v4, CommentionsServiceProvider::packageBooted() uses Livewire::addNamespace() for component discovery. This works in development (PHP CLI, validate_timestamps=1) but fails in production under Apache mod_php + OPcache with validate_timestamps=0.
Root cause
Livewire v4's Finder::resolveClassComponentClassName() handles namespaced components (commentions::*) in a dedicated branch that:
- Generates a class name from convention (
Kirschbaum\Commentions\Livewire\Comments)
- Calls
class_exists($class)
- If
class_exists() returns false, returns null immediately — it never falls through to check classComponents or any other resolution path
Under Apache + OPcache with validate_timestamps=0 and Composer's optimize-autoloader, class_exists() can return false for vendor classes that weren't in the OPcache file cache at build time. This causes a ComponentNotFoundException for all Commentions Livewire components.
The v3 branch uses explicit Livewire::component() calls which bypass class_exists() entirely — that's why v3 never had this issue.
Relevant Livewire v4 code (Finder::resolveClassComponentClassName)
public function resolveClassComponentClassName($name): ?string
{
[$namespace, $componentName] = $this->parseNamespaceAndName($name);
if ($namespace !== null) {
if (isset($this->classNamespaces[$namespace]['classNamespace'])) {
$class = $this->generateClassFromName($componentName, [$this->classNamespaces[$namespace]['classNamespace']]);
if (class_exists($class)) {
return $class;
}
}
return null; // ← never falls through to classComponents
}
// classComponents check is unreachable for namespaced components
if (isset($this->classComponents[$name])) {
return $this->classComponents[$name];
}
// ...
}
Suggested fix
Add Livewire::resolveMissingComponent() as a fallback alongside addNamespace(). This is the only hook in Livewire v4's Factory::resolveComponentNameAndClass() that runs after all resolution paths fail:
if ($this->isLivewireV4()) {
Livewire::addNamespace('commentions', classNamespace: __NAMESPACE__ . '\\Livewire');
// Explicit fallback: addNamespace() relies on class_exists() which can fail
// under Apache + OPcache (validate_timestamps=0) when vendor classes aren't
// in the OPcache file cache. resolveMissingComponent runs after all other
// resolution paths fail, ensuring components are always found.
Livewire::resolveMissingComponent(fn (string $name) => match ($name) {
'commentions::comment' => Comment::class,
'commentions::comment-list' => CommentList::class,
'commentions::comments' => Comments::class,
'commentions::reactions' => Reactions::class,
'commentions::subscription-sidebar' => SubscriptionSidebar::class,
default => null,
});
} else {
// ... existing v3 registrations
}
Environment
- Commentions: v0.7.10
- Livewire: v4
- PHP: 8.4, Apache mod_php
- OPcache:
validate_timestamps=0, Composer optimize-autoloader: true
- Deployment: Docker on AWS ECS Fargate
Workaround
Add the resolveMissingComponent() fallback in your application's AppServiceProvider::boot() method until this is fixed upstream.
Happy to submit a PR if you'd like.
Description
On Livewire v4,
CommentionsServiceProvider::packageBooted()usesLivewire::addNamespace()for component discovery. This works in development (PHP CLI,validate_timestamps=1) but fails in production under Apache mod_php + OPcache withvalidate_timestamps=0.Root cause
Livewire v4's
Finder::resolveClassComponentClassName()handles namespaced components (commentions::*) in a dedicated branch that:Kirschbaum\Commentions\Livewire\Comments)class_exists($class)class_exists()returns false, returnsnullimmediately — it never falls through to checkclassComponentsor any other resolution pathUnder Apache + OPcache with
validate_timestamps=0and Composer'soptimize-autoloader,class_exists()can returnfalsefor vendor classes that weren't in the OPcache file cache at build time. This causes aComponentNotFoundExceptionfor all Commentions Livewire components.The v3 branch uses explicit
Livewire::component()calls which bypassclass_exists()entirely — that's why v3 never had this issue.Relevant Livewire v4 code (
Finder::resolveClassComponentClassName)Suggested fix
Add
Livewire::resolveMissingComponent()as a fallback alongsideaddNamespace(). This is the only hook in Livewire v4'sFactory::resolveComponentNameAndClass()that runs after all resolution paths fail:Environment
validate_timestamps=0, Composeroptimize-autoloader: trueWorkaround
Add the
resolveMissingComponent()fallback in your application'sAppServiceProvider::boot()method until this is fixed upstream.Happy to submit a PR if you'd like.