Problem/Motivation
Steps to reproduce
On Drupal 10.3+/11, \Drupal\datetime_range\DateTimeRangeTrait::renderStartEndWithIsoAttribute() declares a native string type on its $separator parameter. OptionalEndDateDateTimeRangeTrait::viewElements() passes $this->getSetting('separator') straight into it (line 29). PluginSettingsBase::getSetting() only merges defaultSettings() when the key is absent from the stored settings, so a stored explicit separator: null is returned as NULL and rendering fatals whenever an item has an end date different from the start date:
Argument #2 ($separator) must be of type string, null given, called in
modules/contrib/optional_end_date/src/OptionalEndDateDateTimeRangeTrait.php on line 29
How a NULL ends up stored in real life: the separator is type: label in config schema, i.e. translatable. If a site translates an entity view display through the configuration translation UI (or a TMGMT job) and leaves the "Separator" field empty, the language collection stores content.FIELD.settings.separator: null. The base configuration still holds '-', so every config inspection looks healthy and the fatal only occurs when rendering in the translated language. Migrated or hand-written display YAML with an explicit null triggers the same crash.
The failure mode is particularly confusing when the field is rendered inside a BigPipe placeholder (e.g. a Views block): for users with a session, BigPipe catches the exception during streaming, logs it and silently drops the placeholder, while anonymous requests (no session, synchronous placeholder rendering) get a hard WSOD/500. The site therefore looks fine to logged-in administrators while anonymous visitors on one language get a 500.
Steps to reproduce
- Drupal 10.3+ or 11 with optional_end_date 2.0.0-beta1 or 2.0.0-beta2, a daterange field displayed with the default formatter, and a node whose end date differs from its start date.
- Enable configuration translation, translate the entity view display and leave "Separator" empty — or store
separator: nullin the display component settings by any other means. - View the node in that language as an anonymous user: the TypeError above is thrown.
8.x-1.x is not affected: it used the separator in plain string concatenation (' ' . $separator . ' '), so a NULL silently degraded to an empty string. The regression appeared when 2.0.x started delegating to core's natively typed helper.
Proposed resolution
Cast the setting to string, restoring the 1.x tolerance:
$separator = (string) $this->getSetting('separator');
Patch attached; applies to both 2.0.x-dev and the 2.0.0-beta2 release.
Note: core's own DateTimeRangeTrait::viewElements() passes the same untyped setting into the same typed helper, so core is exposed to the identical crash — this module simply reaches it first because it swaps the class of the core daterange formatters. A core follow-up may be warranted.
Remaining tasks
Review / commit. Optionally a kernel test asserting that a formatter with 'separator' => NULL in its settings renders without error.
| Comment | File | Size | Author |
|---|---|---|---|
| optional_end_date-cast-separator-to-string.patch | 861 bytes | jrochate |
Comments
Comment #2
jrochate commentedComment #4
birk commentedThank you for the issue and patch.