Problem/Motivation

On the response time sensor edit form (/admin/config/system/monitoring/sensors/response_time), changing the Threshold type dropdown — or any other Ajax-triggering select on the form (Sensor Plugin, Value type) — fails silently: the thresholds section is not refreshed with the new warning/critical fields, and subsequent form interactions are broken.

Under the hood it is a PHP 8 TypeError:

TypeError: implode(): Argument #2 ($array) must be of type ?array, string given
in ResponseTimeSensorPlugin.php:79

…raised during the Ajax rebuild of the sensor form.

Steps to reproduce

  1. Edit the response_time sensor.
  2. Type any path into the Paths to exclude textarea (for example /admin/foo/*).
  3. Change the Threshold type dropdown (for example Exceeds → Falls).
  4. Observe that the threshold fields do not refresh. The watchdog shows the TypeError.

Same failure path on the Sensor Plugin and Value type Ajax dropdowns when the sensor has text in the excluded-paths field.

Root cause

This was introduced in #3562444. ResponseTimeSensorPlugin::buildConfigurationForm() assumes excluded_paths is always an array:

'#default_value' => ($this->sensorConfig->getSetting('excluded_paths'))
  ? implode(PHP_EOL, $this->sensorConfig->getSetting('excluded_paths'))
  : '',

On a form rebuild the entity form's copyFormValuesToEntity() has already written the raw textarea string onto $entity->settings['excluded_paths']. The plugin's own submitConfigurationForm() splits that string into an array, but submit handlers don't run on rebuilds. So the next build sees a string, PHP 8's strict-typed implode() raises, the Ajax callback dies, and the thresholds wrapper is never replaced.

Proposed resolution

Split the textarea into an array during form validation via #element_validate, so the value stored in form state is an array by the time copyFormValuesToEntity() writes it back to the entity. This keeps the stored type invariant across rebuilds and lets the custom submitConfigurationForm() splitting be removed entirely.

$excluded = $this->sensorConfig->getSetting('excluded_paths') ?: [];
$form['excluded_paths'] = [
  '#type' => 'textarea',
  '#title' => $this->t('Paths to exclude'),
  '#default_value' => is_array($excluded) ? implode(PHP_EOL, $excluded) : (string) $excluded,
  '#description' => $this->t('Supports wildcards. One path per line. Include starting slash. I.e. /foo/bar'),
  '#element_validate' => [[static::class, 'splitExcludedPaths']],
];

public static function splitExcludedPaths(array &$element, FormStateInterface $form_state): void {
  $paths = array_values(array_filter(
    array_map('trim', preg_split('/\R+/', (string) $element['#value'])),
    'strlen'
  ));
  $form_state->setValueForElement($element, $paths);
}

The is_array(...) fallback on the default value handles one-time migration of configs mis-saved as strings by the current buggy code path.

Remaining tasks

  • Apply the #element_validate fix.
  • Remove the now-redundant submitConfigurationForm() splitting.

User interface changes

None, other than Ajax interactions on the sensor form actually working.

API changes

None. excluded_paths remains a sequence of strings in config schema.

Data model changes

None.

Issue fork monitoring-3586658

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mably created an issue. See original summary.

mably’s picture

Status: Active » Needs review

  • berdir committed d43427b3 on 8.x-1.x authored by mably
    fix: #3586658 Threshold type (and other Ajax dropdowns) fails to refresh...
berdir’s picture

Version: 8.x-1.21 » 8.x-1.x-dev
Status: Needs review » Fixed

Merged.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.