{"record":{"id":"5aefc839345e556c","repo":"octobercms/october","slug":"backend-lang-form-behavior-not-ready-5aefc8","errorCode":"backend::lang.form.behavior_not_ready","errorMessage":"Form behavior has not been initialized, check that you have called initForm() in your controller.","messagePattern":"Form behavior has not been initialized, check that you have called initForm\\(\\) in your controller\\.","errorType":"exception","errorClass":"ApplicationException","httpStatus":null,"severity":"error","filePath":"modules/system/controllers/Settings.php","lineNumber":161,"sourceCode":"     */\n    public function update_onResetDefault($author, $plugin, $code = null)\n    {\n        $item = $this->findSettingItem($author, $plugin, $code);\n        $model = $this->createModel($item);\n        $model->resetDefault();\n\n        Flash::success(Lang::get('backend::lang.form.reset_success'));\n\n        return Backend::redirect('system/settings/update/'.$author.'/'.$plugin.'/'.$code);\n    }\n\n    /**\n     * formRender renders the form\n     */\n    public function formRender($options = [])\n    {\n        if (!$this->formWidget) {\n            throw new ApplicationException(Lang::get('backend::lang.form.behavior_not_ready'));\n        }\n\n        return $this->formWidget->render($options);\n    }\n\n    /**\n     * initWidgets prepare the widgets used by this action\n     * @param Model $model\n     */\n    protected function initWidgets($model)\n    {\n        $config = $model->getFieldConfig();\n        $config->model = $model;\n        $config->arrayName = class_basename($model);\n        $config->context = 'update';\n\n        $widget = $this->makeWidget(\\Backend\\Widgets\\Form::class, $config);\n        $widget->bindToController();","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/system/controllers/Settings.php#L143-L179","documentation":"The Settings controller overrides formRender() to delegate to formWidget->render(). formWidget is only built during the update() flow (findSettingItem -> createModel -> initWidgets). If formRender() is reached before that — typically because update() aborted earlier (e.g. item not found or model missing) yet a view still calls it, or a custom action invokes it directly — backend::lang.form.behavior_not_ready is thrown.","triggerScenarios":"A custom settings view/partial calling $this->formRender() on an error path where initWidgets never ran; an AJAX handler or custom action on the Settings controller rendering the form without first building the widget.","commonSituations":"Backend view overrides that unconditionally render the form; extensions adding settings actions that skip createModel/initWidgets; the underlying update() error masking itself as this secondary failure.","solutions":["Fix the upstream error that aborts update() ('Unable to find the specified settings.' or the missing-model error) — formRender then initializes normally","In custom actions, replicate the update() flow: findSettingItem -> createModel -> initWidgets, then formRender","Guard custom partials so they render the form only when the widget exists"],"exampleFix":"// before: custom action renders the form without building the widget\npublic function mySettings($author, $plugin, $code = null)\n{\n    return $this->formRender(); // formWidget is null\n}\n\n// after\npublic function mySettings($author, $plugin, $code = null)\n{\n    if (!$item = $this->findSettingItem($author, $plugin, $code)) {\n        throw new ApplicationException(__('Unable to find the specified settings.'));\n    }\n    $model = $this->createModel($item);\n    $this->initWidgets($model);\n    return $this->formRender();\n}","handlingStrategy":"type-guard","validationCode":"// in a custom Settings controller action, before rendering any form partial\nif ($this->formWidget === null) {\n    // build it: findSettingItem -> createModel -> initWidgets, or skip rendering\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Follow the update() flow (item -> model -> initWidgets) before any formRender call","Fix the primary error that aborts update(); this exception is usually secondary","In overridden views, render the form conditionally so error paths skip it"],"tags":["backend","form","settings","widget"],"backgroundTag":"widget-not-initialized","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}