Summary
Several layers in the bright style filter on numeric OMT properties using ordered comparison operators (>=, <, <=). When a vector-tile feature has that property as null (common on some POI / boundary / road features), MapLibre GL throws during tile parsing:
Expected value to be of type number, but found null instead.
Ordered comparisons require numbers on both sides (unlike == / !=, which are loose), so a null value throws. The feature is dropped and the error is logged from the tile worker on every affected tile — at city zoom the POI rank filters fire continuously.
Affected layers / expressions (deployed bright)
poi_r1 — [">=", ["get","rank"], 1], ["<", ["get","rank"], 7]
poi_r7 — [">=", ["get","rank"], 7], ["<", ["get","rank"], 20]
poi_r20 — [">=", ["get","rank"], 20]
label_country_3 — [">=", ["get","rank"], 3]
boundary_3 — [">=", ["get","admin_level"], 3], ["<=", ["get","admin_level"], 6]
highway-shield-non-us, highway-shield-us-interstate, road_shield_us — ["<=", ["get","ref_length"], 6]
POI rank is by far the most frequently hit.
Reproduce
- maplibre-gl-js v4.7.1
- Load the
bright style and pan to a dense city (e.g. Chicago); the console fills with Expected value to be of type number, but found null from the tile worker.
Suggested fix
Make the property null-safe before the ordered comparison, e.g.:
[">=", ["coalesce", ["get", "rank"], 9999], 1]
(or ["to-number", ["get","rank"], 9999]). The default is a styling choice — a null rank could be treated as least-prominent. Same wrap applies to admin_level / ref_length. Happy to open a PR if you have a preferred direction (coalesce default vs a ["has", …] guard).
Summary
Several layers in the
brightstyle filter on numeric OMT properties using ordered comparison operators (>=,<,<=). When a vector-tile feature has that property asnull(common on some POI / boundary / road features), MapLibre GL throws during tile parsing:Ordered comparisons require numbers on both sides (unlike
==/!=, which are loose), so anullvalue throws. The feature is dropped and the error is logged from the tile worker on every affected tile — at city zoom the POIrankfilters fire continuously.Affected layers / expressions (deployed
bright)poi_r1—[">=", ["get","rank"], 1],["<", ["get","rank"], 7]poi_r7—[">=", ["get","rank"], 7],["<", ["get","rank"], 20]poi_r20—[">=", ["get","rank"], 20]label_country_3—[">=", ["get","rank"], 3]boundary_3—[">=", ["get","admin_level"], 3],["<=", ["get","admin_level"], 6]highway-shield-non-us,highway-shield-us-interstate,road_shield_us—["<=", ["get","ref_length"], 6]POI
rankis by far the most frequently hit.Reproduce
brightstyle and pan to a dense city (e.g. Chicago); the console fills withExpected value to be of type number, but found nullfrom the tile worker.Suggested fix
Make the property null-safe before the ordered comparison, e.g.:
(or
["to-number", ["get","rank"], 9999]). The default is a styling choice — anullrank could be treated as least-prominent. Same wrap applies toadmin_level/ref_length. Happy to open a PR if you have a preferred direction (coalesce default vs a["has", …]guard).