Problem/Motivation
The Paragraphs Table module's clone form (`ParagraphCloneForm`) causes a fatal error in Drupal 11 when attempting to clone a paragraph.
The `ParagraphCloneForm` does not set a `#title` before calling the parent `buildForm()`. In Drupal 11, this leads to a `TypeError` during page rendering when the (null) title is passed to `Html::escape()` in `FormattableMarkup.php`.
Other forms in the module (add, edit, delete) avoid this by either setting a title explicitly or inheriting one from the route definition.
In this case, the paragraph being cloned is embedded inside another paragraph (nested), and its type does not define a label field. As a result, `$paragraph->label()` returns `NULL`, which causes the fatal error described.
**Note:** The Paragraphs module does not allow you to configure a label field via the UI. As a result, many paragraph types — especially nested ones — do not have a defined label, and `$paragraph->label()` simply returns `NULL`.
Steps to reproduce
1. Ensure you're using **Drupal 11** and the **Paragraphs Table** module is installed.
2. Create a **Paragraph type** (e.g., “Assignment”) that includes a **Paragraphs Table field** (e.g., a `table` field of type Paragraphs Table).
3. Create another **Paragraph type** (e.g., “Row”) that is used inside the table.
4. Add several “Row” paragraphs inside an “Assignment” paragraph using the Paragraphs Table field.
5. Navigate to the Paragraphs Table view and click the **“Duplicate”** operation for one of the nested “Row” paragraphs.
6. Observe that the page throws a **TypeError** due to `Html::escape(NULL)`.
Proposed resolution
Update the `ParagraphCloneForm::buildForm()` method to explicitly set a fallback title **before** calling `parent::buildForm()`. This ensures the form always has a valid, non-null `#title`, avoiding the fatal error.
Suggested fix:
```php
public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
// Ensure the form has a page title.
$form['#title'] = $this->t('Duplicate paragraph: @label', [
'@label' => $this->entity->label() ?: $this->t('(No label)'),
]);
return $form;
}
```
Remaining tasks
- Confirm that the proposed fix prevents the fatal error when `$paragraph->label()` returns `NULL`.
- Optionally: Create and review a patch with the proposed fix.
- Test with nested paragraph types that lack label fields.
- Optionally: Discuss whether Paragraphs module should expose a label field configuration.
User interface changes
None, unless the error occurs — in which case this change prevents the form from breaking.
API changes
None.
This fix only modifies the internal behavior of ParagraphCloneForm::buildForm() by ensuring a safe value is passed to #title. No public methods, services, or APIs are introduced or altered.
Data model changes
None.
This fix does not alter the structure or storage of paragraph entities.