octobercms/october · error · SystemException
NestedForm must specify either a "form" property for the for
Error message
NestedForm must specify either a "form" property for the form fields
What it means
NestedFormField builds its nested fieldset solely from the `form:` key of the field config (the constructor only assigns fieldsetConfig when isset($config['form'])). validateConfig() requires a non-null fieldsetConfig, so a nestedform field without a `form:` block — nothing to render or extend into the model — throws a SystemException.
Source
Thrown at modules/tailor/contentfields/NestedFormField.php:40
public $fieldsetConfig;
/**
* defineConfig will process the field configuration.
*/
public function defineConfig(array $config)
{
if (isset($config['form'])) {
$this->fieldsetConfig = (array) $config['form'];
}
}
/**
* validateConfig
*/
public function validateConfig()
{
if ($this->fieldsetConfig === null) {
throw new SystemException('NestedForm must specify either a "form" property for the form fields');
}
}
/**
* defineFormField will define how a field is displayed in a form.
*/
public function defineFormField(FormElement $form, $context = null)
{
$form->addFormField($this->fieldName, $this->label)->defaultCreate()->useConfig($this->getCleanFormConfig());
}
/**
* defineBatchListColumn
*/
public function defineBatchListColumn(ListElement $list, $context = null)
{
$list->defineColumn($this->fieldName, $this->label);
}View on GitHub (pinned to b608633a7e)
Solutions
- Add a `form:` block containing a `fields:` map under the nestedform field.
- Check indentation so `form:` is a direct child of the field and actually contains fields.
- If you only need a single level of nested fields without form nesting, use a regular field group instead.
Example fix
# before
fields:
address:
label: Address
type: nestedform
# after
fields:
address:
label: Address
type: nestedform
form:
fields:
street:
type: text
city:
type: text Defensive patterns
Strategy: validation
Validate before calling
$fieldConfig = $blueprintContent['fields'][$fieldName] ?? [];
if (($fieldConfig['type'] ?? '') === 'nestedform' && !isset($fieldConfig['form'])) {
throw new InvalidArgumentException("nestedform field '{$fieldName}' requires a form: block.");
} Type guard
function hasFormBlock(array $fieldConfig): bool
{
return isset($fieldConfig['form']) && is_array($fieldConfig['form']);
} Try / catch
try {
// blueprint validation / tailor:refresh
} catch (\SystemException $e) {
// add form: { fields: { ... } } under the nestedform field and revalidate
} Prevention
- Author nestedform fields from a snippet that already includes a form.fields skeleton.
- Validate blueprint YAML structure in CI before deploy.
When it happens
Trigger: A field `{type: nestedform}` is defined with no `form:` key, or `form:` is present but empty/unparsed so isset() fails or the value doesn't reach the constructor. Validation runs when Tailor compiles the blueprint fieldset.
Common situations: Expecting nestedform to work like a partial without config; YAML indentation placing `form` under the wrong level; a `form:` value that parses to null; fieldsets imported from other projects missing the form block.
Related errors
- NestedItems must specify either a "form" property for the fo
- Type must be one of: {$typeAsString}.
- Field name is reserved: {$fieldName}.
- Invalid source reference '{$source}'. No blueprint found wit
- Blueprint not found
AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21).
Data as JSON: /api/errors/bff20dec19710a9e.
Report an issue: GitHub.