Clone form causes error due to null label (Drupal 11 compatibility)

Created on 4 April 2025, about 1 month ago

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.

🐛 Bug report
Status

Active

Version

2.0

Component

Code

Created by

🇪🇸Spain marjose

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024