octobercms/october · error · SystemException
Vue component class must be a descendant of Backend\Classes\
Error message
Vue component class must be a descendant of Backend\Classes\VueComponentBase: %s
What it means
Even when the class exists, makeVueComponent() requires it to be a subclass of Backend\Classes\VueComponentBase (is_subclass_of), because registration drives Vue-component-specific APIs: dependency resolution, template paths, and ESM registration. A class extending a widget, controller, or nothing at all fails here with the class name included.
Source
Thrown at modules/backend/traits/VueMaker.php:216
$path = substr($path, strlen($basePath));
}
$path = str_replace('\\', '/', $path);
return Request::getBasePath() . '/' . ltrim($path, '/');
}
/**
* makeVueComponent
*/
protected function makeVueComponent($className)
{
if (!class_exists($className)) {
throw new SystemException(sprintf('Vue component class not found: %s', $className));
}
if (!is_subclass_of($className, VueComponentBase::class)) {
throw new SystemException(
sprintf('Vue component class must be a descendant of Backend\Classes\VueComponentBase: %s', $className)
);
}
return new $className($this);
}
/**
* isVueComponentRegistered
*/
protected function isVueComponentRegistered($className)
{
return isset($this->vueComponentClasses[$className]);
}
}
View on GitHub (pinned to b608633a7e)
Solutions
- Change the class to extend Backend\Classes\VueComponentBase.
- If you meant a form widget, use makeFormWidget()/registerFormWidgets() instead of the Vue component pipeline.
- Check that the class string is not pointing at a helper or a final intermediate class.
Example fix
// before
class MediaManager extends \Backend\Classes\WidgetBase
{
}
// after
use Backend\Classes\VueComponentBase;
class MediaManager extends VueComponentBase
{
} Defensive patterns
Strategy: validation
Validate before calling
if (!is_subclass_of($class, \Backend\Classes\VueComponentBase::class)) {
throw new InvalidArgumentException(
$class . ' must extend VueComponentBase to be registered as a Vue component'
);
}
$this->registerVueComponent($class); Type guard
function isRegistrableVueComponent(string $class): bool
{
return class_exists($class)
&& is_subclass_of($class, \Backend\Classes\VueComponentBase::class);
} Prevention
- Start every backend Vue component from a VueComponentBase stub
- Keep form widgets and Vue components in separate namespaces to avoid mixups
When it happens
Trigger: registerVueComponent('Acme\Demo\SomeService') where SomeService extends another base (e.g. WidgetBase or FormWidgetBase) or no base at all; passing a helper class name where a Vue component was expected.
Common situations: Confusing backend Vue components with form widgets; copying a widget class as a template for a Vue component and forgetting to change the parent; restructuring class hierarchies during upgrades.
Related errors
- getDependencies() must return an array: %s
- Vue component class not found: %s
- Dynamic Inspector control options cannot be loaded for the s
- A widget class name ':name' has not been registered
- Dropdown menu item label is not provided for item type :type
AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21).
Data as JSON: /api/errors/804b38ae6666eb90.
Report an issue: GitHub.