octobercms/october · error · ApplicationException
Dynamic Inspector control options cannot be loaded for the s
Error message
Dynamic Inspector control options cannot be loaded for the specified class.
What it means
onInspectableGetOptions only resolves dynamic options for classes whose hierarchy includes System\Traits\PropertyContainer, verified with class_uses_recursive(). Any other class — even one that exists and autoloads — is rejected, because the handler instantiates the class and calls property APIs that only that trait provides. This is a server-side contract check on the class named by inspectorClassName.
Source
Thrown at modules/backend/traits/InspectableContainer.php:35
*/
public function onInspectableGetOptions()
{
// Disable asset broadcasting
$this->flushAssets();
$property = trim(post('inspectorProperty'));
if (!$property) {
throw new ApplicationException('The property name is not specified.');
}
$className = trim(post('inspectorClassName'));
if (!$className || $className === 'undefined') {
throw new ApplicationException('The inspectable class name is not specified.');
}
$traitFound = in_array(\System\Traits\PropertyContainer::class, class_uses_recursive($className));
if (!$traitFound) {
throw new ApplicationException('Dynamic Inspector control options cannot be loaded for the specified class.');
}
$obj = new $className(null);
$obj->setProperties(post());
// Nested properties have names like object.property.
// Convert them to Object.Property.
$propertyNameParts = explode('.', $property);
$propertyMethodName = '';
foreach ($propertyNameParts as $part) {
$part = trim($part);
if (!strlen($part)) {
continue;
}
$propertyMethodName .= ucfirst($part);
}View on GitHub (pinned to b608633a7e)
Solutions
- Make the target class use System\Traits\PropertyContainer — directly, or by extending a base like Cms\Classes\ComponentBase that already includes it.
- Double-check the fully-qualified class name posted as inspectorClassName; a wrong-but-existing class fails exactly here.
- After moving or renaming classes, run composer dump-autoload and clear caches.
Example fix
// before
class StockReports
{
}
// after
class StockReports
{
use \System\Traits\PropertyContainer;
}
// or extend a base that already provides the trait
class StockReports extends \Cms\Classes\ComponentBase
{
} Defensive patterns
Strategy: validation
Validate before calling
// Before pointing an inspector at a class, verify the contract server-side
$usable = class_exists($className)
&& in_array(\System\Traits\PropertyContainer::class, class_uses_recursive($className), true);
if (!$usable) {
// choose a class that uses PropertyContainer, e.g. a ComponentBase
} Type guard
function isPropertyContainerClass(string $class): bool
{
return class_exists($class)
&& in_array(\System\Traits\PropertyContainer::class, class_uses_recursive($class), true);
} Prevention
- Only use ComponentBase/WidgetBase-style classes as dynamic-options providers
- Add a boot-time assertion for inspectable classes referenced in inspector configs
- Re-run the class_uses_recursive check in tests after upgrading the CMS
When it happens
Trigger: POST with a valid inspectorProperty and an existing inspectorClassName whose class tree does not include System\Traits\PropertyContainer — for example a plain PHP helper class, a DTO, or a model.
Common situations: Pointing an inspector control's dynamic options at a helper/DTO instead of a component; plugin authors exposing a new inspectable class but forgetting the trait; upgrades that restructured base classes and dropped the trait from the hierarchy.
Related errors
- Object list value should be an object. Property: ${this.prop
- Values not found for the selected row.
- Trying to get selected row without a popup reference.
- The property name is not specified.
- The inspectable class name is not specified.
AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21).
Data as JSON: /api/errors/c3edd89104471f11.
Report an issue: GitHub.