{"record":{"id":"b8276316d34b40fa","repo":"octobercms/october","slug":"nesteditems-must-specify-either-a-form-property","errorCode":null,"errorMessage":"NestedItems must specify either a \"form\" property for the form fields","messagePattern":"NestedItems must specify either a \"form\" property for the form fields","errorType":"exception","errorClass":"SystemException","httpStatus":null,"severity":"error","filePath":"modules/tailor/contentfields/NestedItemsField.php","lineNumber":40,"sourceCode":"    public $fieldsetConfig;\n\n    /**\n     * defineConfig will process the field configuration.\n     */\n    public function defineConfig(array $config)\n    {\n        if (isset($config['form'])) {\n            $this->fieldsetConfig = (array) $config['form'];\n        }\n    }\n\n    /**\n     * validateConfig\n     */\n    public function validateConfig()\n    {\n        if ($this->fieldsetConfig === null) {\n            throw new SystemException('NestedItems must specify either a \"form\" property for the form fields');\n        }\n    }\n\n    /**\n     * defineFormField will define how a field is displayed in a form.\n     */\n    public function defineFormField(FormElement $form, $context = null)\n    {\n        $fieldConfig = [\n            'label' => $this->label,\n            'list' => [],\n            'form' => [],\n            'customMessages' => (array) $this->customMessages,\n            'popupSize' => $this->popupSize,\n            'view' => [\n                'showSorting' => false,\n                'toolbarButtons' => 'create|delete',\n                'recordsPerPage' => $this->recordsPerPage,","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/tailor/contentfields/NestedItemsField.php#L22-L58","documentation":"NestedItemsField (repeatable nested item sets) builds its fieldset solely from the `form:` key of the field config, exactly like nestedform. validateConfig() throws when fieldsetConfig is null, i.e. the field was declared without a usable `form:` block.","triggerScenarios":"A field `{type: nesteditems}` is defined with no `form:` key, or the key exists but is empty/indentation-broken so the constructor never assigns fieldsetConfig. The error surfaces when Tailor validates or compiles the blueprint.","commonSituations":"Copy-pasting a nesteditems example that omits form; intending to configure items via `fields:` (unsupported — nesteditems uses `form:`); indentation errors after refactoring YAML.","solutions":["Add a `form:` block with a `fields:` map under the nesteditems field.","If you used `fields:` instead of `form:`, rename the key — nesteditems expects `form:`.","Verify YAML indentation so `form:` parses as part of the field config."],"exampleFix":"# before\nfields:\n  specs:\n    label: Specs\n    type: nesteditems\n    fields:\n      name: { type: text }\n\n# after\nfields:\n  specs:\n    label: Specs\n    type: nesteditems\n    form:\n      fields:\n        name: { type: text }","handlingStrategy":"validation","validationCode":"$fieldConfig = $blueprintContent['fields'][$fieldName] ?? [];\nif (($fieldConfig['type'] ?? '') === 'nesteditems' && !isset($fieldConfig['form'])) {\n    throw new InvalidArgumentException(\"nesteditems field '{$fieldName}' requires a form: block (not fields:).\");\n}","typeGuard":"function hasNestedItemsForm(array $fieldConfig): bool\n{\n    return isset($fieldConfig['form']) && is_array($fieldConfig['form']);\n}","tryCatchPattern":"try {\n    // blueprint validation / tailor:refresh\n} catch (\\SystemException $e) {\n    // nesteditems needs form:, not fields: — rename the key and revalidate\n}","preventionTips":["Remember nesteditems/nestedform take `form:`, unlike top-level blueprint sections which take `fields:`.","Lint blueprint YAML in CI for field types requiring form blocks."],"tags":["tailor","nesteditems","field-config","blueprint"],"backgroundTag":"missing-required-config","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}