ARTICLE AD BOX
I am trying to add custom validation for a custom inline block type in Drupal 10 Layout Builder.
The UI logic (#states) works correctly, but my custom #validate callback never executes inside the Layout Builder modal form.
I have already spent a lot of time debugging this and would appreciate guidance on the correct Drupal approach for validating inline block forms in Layout Builder.
Context:
Custom block type:
v2_bannerRequirements:
If field_v2_is_fully_clickable = TRUE
field_v2_link is requiredIf field_v2_is_fully_clickable = FALSE
field_v2_buttons_x2 is requiredfield_v2_title OR body required
Initially I implemented this using Entity Constraints + Constraint Validators, but Layout Builder AJAX forms crashed with:
Undefined array key "#parents"because of ->atPath() usage during AJAX rebuilds.
So I moved validation into Form API validation.
Hooks in .module
final class FormAlterHooks { private function getFormEntityType(array $form, FormStateInterface $form_state): ?string { $form_object = $form_state->getFormObject(); if ($form_object instanceof EntityFormInterface) { $entity = $form_object->getEntity(); return "{$entity->getEntityType()->id()}:{$entity->bundle()}"; } elseif ($form_object instanceof LayoutBuilderForm) { if (empty($form['#block'])) { return NULL; } $block = $form['#block']; return "{$block->getEntityType()->id()}:{$block->bundle()}"; } return NULL; } public function bannerBlockFormAlter( &$form, FormStateInterface $form_state, $form_id ): void { if ($this->getFormEntityType($form, $form_state) !== 'block_content:v2_banner') { return; } // Validation callback. if (!empty($form['settings']['block_form'])) { $form['settings']['block_form']['#validate'][] = [ self::class, 'validateBannerForm' ]; } else { $form['#validate'][] = [ self::class, 'validateBannerForm' ]; } // States logic works correctly. $form['field_v2_link']['#states']['visible'] = [ ':input[name="field_v2_is_fully_clickable[value]"]' => ['checked' => TRUE], ]; $form['field_v2_buttons_x2']['#states']['visible'] = [ ':input[name="field_v2_is_fully_clickable[value]"]' => ['checked' => FALSE], ]; } public static function validateBannerForm( array &$form, FormStateInterface $form_state ): void { throw new \Exception('VALIDATION RUNNING'); } } hook_form_layout_builder_add_block_alter() executes hook_form_layout_builder_update_block_alter() executes #states logic works correctly form alter definitely runs Layout Builder modal loads correctly
The validation callback never executes.
Even this never triggers:
throw new \Exception('VALIDATION RUNNING');No exception appears anywhere:
no AJAX error no logs no exception pageI also previously tried:
Entity Constraints Constraint Validators ->atPath() $form['#entity_builders'] $form['#element_validate']but Layout Builder AJAX forms became unstable.
What is the correct Drupal 10 approach for attaching custom validation to Layout Builder inline block forms? Any guidance or examples would be appreciated.
