octobercms/october · error · ApplicationException
Class :class must define property $:property used by :behavi
Error message
Class :class must define property $:property used by :behavior behavior.
What it means
ModelBehavior is the base class for model behaviors attached via public $implement (e.g. System\Behaviors\SettingsModel). Its constructor iterates $requiredProperties and checks each against the host model instance with isset(); any missing property throws ApplicationException with the lang key system::lang.behavior.missing_property, naming the model class, the property, and the behavior. SettingsModel for example requires $settingsFields and $settingsCode on the model.
Source
Thrown at modules/system/classes/ModelBehavior.php:32
{
/**
* @var array requiredProperties that must exist in the model using this behavior.
*/
protected $requiredProperties = [];
/**
* __construct
* @param \October\Rain\Database\Model $model The extended model.
* @throws ApplicationException
*/
public function __construct($model)
{
parent::__construct($model);
// Validate model properties
foreach ($this->requiredProperties as $property) {
if (!isset($model->{$property})) {
throw new ApplicationException(Lang::get('system::lang.behavior.missing_property', [
'class' => get_class($model),
'property' => $property,
'behavior' => get_called_class()
]));
}
}
}
}
View on GitHub (pinned to b608633a7e)
Solutions
- Add the missing public property to the model class — the message names exactly which property and which behavior demanded it.
- Ensure the property is public and spelled exactly as required (e.g. $settingsCode, $settingsFields for SettingsModel).
- For your own behaviors, review requiredProperties and declare each listed key on the consuming model.
Example fix
// before
class Settings extends Model
{
public $implement = ['System.Behaviors.SettingsModel'];
}
// after
class Settings extends Model
{
public $implement = ['System.Behaviors.SettingsModel'];
public $settingsCode = 'acme.blog.settings';
public $settingsFields = 'settings.yaml';
} Defensive patterns
Strategy: validation
Validate before calling
// Before attaching a behavior, confirm the model defines every required property
function behaviorRequirementsMet(string $modelClass, array $requiredProperties): bool
{
foreach ($requiredProperties as $property) {
if (!property_exists($modelClass, $property)) {
return false;
}
}
return true;
} Type guard
function hasSettingsBehaviorConfig(string $modelClass): bool
{
return property_exists($modelClass, 'settingsCode')
&& property_exists($modelClass, 'settingsFields');
} Try / catch
try {
$model->addBehavior(System\Behaviors\SettingsModel::class);
} catch (\October\Rain\Exception\ApplicationException $e) {
// surface to the developer at boot, not at request time
throw new RuntimeException('Settings model misconfigured: ' . $e->getMessage(), 0, $e);
} Prevention
- Declare required behavior properties as public on the model ($settingsCode, $settingsFields for SettingsModel).
- Add a boot-time assertion in plugin tests that instantiates every implemented model and behavior pair.
- Read the error text — it names the exact class, property, and behavior.
When it happens
Trigger: Declaring public $implement = ['System.Behaviors.SettingsModel']; on a model without also declaring public $settingsCode = 'acme.blog.settings'; and public $settingsFields = 'settings.yaml';; attaching any custom behavior that sets $requiredProperties to a model lacking those public properties.
Common situations: First-time settings-model setup following docs partially; refactoring a settings model and dropping a property; custom behaviors written by plugin authors who list required config keys the consumer forgot; property declared but not public (protected visibility fails isset($model->...) from outside).
Related errors
- Key property ${keyProperty} is not found in the Inspector da
- getDependencies() must return an array: %s
- Vue component class not found: %s
- Vue component class must be a descendant of Backend\Classes\
- A widget class name ':name' has not been registered
AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21).
Data as JSON: /api/errors/2595e8bd682bec7d.
Report an issue: GitHub.