Skip to content
LibxaFrame
Engineering 12 August 2026 4 min read

The framework shipped an admin panel whose routes never resolved

Nova took $resourceKey in its controllers and declared {resource} in its routes, so the container could not resolve the parameter and every one of its routes raised an error instead of rendering. It also claimed /admin, which is how it was finally noticed.

LibxaFrame shipped an admin panel called Nova. It has been removed in 0.11.0, because it never worked, and nobody had noticed.

The bug

Its routes declared one parameter name:

$router->get('/{resource}', [NovaController::class, 'index']);

And its controller took another:

public function index(string $resourceKey, Request $request): Response

The container resolves controller arguments by name. {resource} does not match $resourceKey, so it could not fill the parameter, and there was no default to fall back to:

Unresolvable dependency: parameter $resourceKey in [closure] has no type hint and no default value.

Every Nova route. Not some of them, not under certain conditions: all of them, always, since whenever that rename happened.

How it was found

Not by anyone using Nova. It was found by installing a different admin package, LibAdmin, and watching it fail.

Nova registered itself among the framework's core providers, at the prefix admin by default. LibAdmin serves at /admin too. Both registered, Nova's routes matched first, and a request to /admin/resources/users produced an error naming $resourceKey — a parameter belonging to a controller in a different package entirely.

So the reported symptom was "the admin package I just installed is broken", and the cause was in the framework, in a module neither package mentioned.

That is a fair illustration of why a framework should not ship an admin panel in its core providers. Two of them cannot coexist, the collision produces an error that names the wrong thing, and the one that wins is decided by registration order rather than by anything the developer chose.

What was removed

Libxa\Nova\*, NovaServiceProvider, and its line in the core provider list. Five files.

The framework's own test suite never touched any of it beyond one autoloading assertion, which is consistent with a module that could not serve a request.

Where an admin panel belongs

In a package, which is where LibAdmin is. It works, it has tests, and its route prefix is configurable, so it can move if something else wants /admin.

Removing public classes is a compatibility break, so this is 0.11.0 rather than a patch: below 1.0 Composer treats the minor number as the boundary, and ^0.10.0 will not pick it up. If you were referencing Libxa\Nova\*, you were referencing something that could not handle a request, and the fix is to stop.

Keep reading