Skip to content

Undefined text property when using mapbox-gl-rtl-text plugin with a formatted text-field of multiple empty sections #35

@Omkarthipparthi

Description

@Omkarthipparthi

Context:
A related issue and proposed fix were opened in the [maplibre-gl-js repository (PR #6545)](maplibre/maplibre-gl-js#6545).
The maintainers there suggested that this problem originates in the mapbox-gl-rtl-text plugin and should be tracked here instead.


What happens:
When the mapbox-gl-rtl-text plugin is used with a formatted text-field expression that consists of multiple sections—all of which evaluate to empty strings (e.g., both ["get", "name"] and ["get", "ref"] return null or "")—the shaping logic ends up producing a text property that becomes undefined.
This leads to runtime errors such as:

“Cannot read properties of undefined (reading 'length')”

This behavior appears when the RTL plugin modifies or wraps the text shaping process and changes the structure of processedLines from arrays to objects.
As a result, this.text becomes undefined instead of an empty string.


Steps to reproduce:

  1. Enable the mapbox-gl-rtl-text plugin.

  2. Add a symbol layer using a formatted text-field like this:

    "text-field": [
      "format",
      ["coalesce", ["get", "name"], ""], {},
      ["coalesce", ["get", "ref"], ""], {}
    ],
    "text-optional": true
  3. Use GeoJSON data where both name and ref are missing or empty.

  4. Observe a runtime error during text shaping/rendering.

Demo: https://jsbin.com/himisusegi/1/edit?html,console,output


Expected behavior:
When all sections evaluate to empty strings, rendering should safely produce no label (or an empty string), not throw an error.


Actual behavior:
When using the RTL plugin:

  • this.text becomes undefined instead of "".
  • A runtime error occurs in the shaping pipeline when attempting to read this.text.length.

Without the RTL plugin, this setup works as expected.


Environment:

  • maplibre-gl-js: 5.7.3
  • mapbox-gl-rtl-text: 0.3.0
  • Browser: Firefox (also reproducible in Chrome)

Possible root cause:
Within shaping.ts, the shaping logic assumes processedLines is an array of arrays, but when the RTL plugin intervenes, it may return an array of objects. This breaks the assumption and leads to an undefined text property.


Suggested resolution / investigation points:

  • Ensure the plugin always returns a valid string (even "") when shaping empty or formatted text sections.
  • Add a defensive guard for undefined text values in the RTL shaping path.
  • Confirm the plugin’s interaction with formatted text-field expressions and multi-section labels.

Related links:

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions