Skip to content

Viewer crashes on bundles with urlPath: null nodes ("Cannot read properties of null (reading 'split')" in matcherFor) #13

Description

@ihor-sviziev

Summary

The hosted viewer (app.screenmap.dev) crashes on load for any bundle that contains a node with urlPath: null, which the format contract allows and which the react-navigation provider produces for every screen missing from the linking config.

Uncaught TypeError: Cannot read properties of null (reading 'split')
    at Lte (index-DzUlHmgp.js:121:7113)      ← matcherFor(urlPath)
    at index-DzUlHmgp.js:121:7330
    at Array.map (<anonymous>)
    at Rte (index-DzUlHmgp.js:121:7310)      ← flowResolution(map)
    at index-DzUlHmgp.js:185:1223
    at Object.useMemo …

Source: apps/visualiser/src/lib/loadBundle.js

function matcherFor(urlPath) {
  const re = urlPath
    .split('/')          // urlPath is null for navigation-only screens

flowResolution() builds a matcher for every node (map.nodes.map((n) => ({ id: n.id, re: matcherFor(n.urlPath) }))), so one URL-less node is enough to take the whole viewer down. The other urlPath uses in the viewer (nodeLabel, the / root lookup in layout.js) are already null-safe.

Reproduction with the repo's own fixture (no external app needed)

cd fixtures/rn-demo-app
node ../../plugins/screenmap/skills/screenmap/scripts/parse-routes.mjs .
mkdir -p .screenmap/out/screens
node ../../plugins/screenmap/skills/screenmap/scripts/pack-map.mjs .
# → "RN Demo-….scrmap" with 5 nodes; Onboarding has "urlPath": null

Drop that bundle on app.screenmap.dev (or apps/visualiser via npm run dev): blank screen + the exception above. The expected-graph.json of that fixture already records "urlPath": null for Onboarding, and docs/scrmap-format.md documents the field as "NULL when the screen has no URL (normal in react-navigation)", so the bundle is conformant; the viewer is the outlier.

Real-world scale: a react-navigation app I mapped (149 screens) has 100 navigation-only screens, so every bundle from it is unloadable in the viewer.

Fix

A URL-less node can never be reached by a deep link, so give it a matcher that matches nothing:

 // Route pattern matching: ties flow deep-link URLs back to nodes.
 function matcherFor(urlPath) {
+  if (urlPath == null) return /(?!)/
   const re = urlPath
     .split('/')

Verified locally against the fixture bundle above and the 149-screen bundle: both load, flows resolve via their screen sidecar fields as before. Happy to open a PR with this if you prefer.

Related (smaller)

plugins/screenmap/skills/screenmap/scripts/render-map.mjs (the static HTML fallback) crashes on v2 flow sidecars for a similar reason: flowsSection() does (f.steps ?? []).map(flowStep), but v2 sidecars key steps by YAML index (an object), so .map is not a function. I have a patch that rebuilds the flat step list from the YAML + sidecar; can include it in the same PR.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions