Skip to content

fix(core): guard material-ref parsers against non-string values (Sentry MONOREPO-EDITOR-EM)#486

Open
anton-pascal wants to merge 1 commit into
mainfrom
fix/sentry-EDITOR-EM
Open

fix(core): guard material-ref parsers against non-string values (Sentry MONOREPO-EDITOR-EM)#486
anton-pascal wants to merge 1 commit into
mainfrom
fix/sentry-EDITOR-EM

Conversation

@anton-pascal

@anton-pascal anton-pascal commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

What

Add a typeof materialRef !== 'string' guard to getLibraryMaterialIdFromRef and getSceneMaterialIdFromRef in packages/core/src/material-library.ts.

Why

Both functions only guarded against null/undefined before calling .startsWith():

if (!materialRef) return null
if (!materialRef.startsWith(PREFIX)) return null   // throws if materialRef is a number/object

When a non-string material ref reaches them (a legacy or malformed wall material slot ref), .startsWith is undefined -> TypeError: e.startsWith is not a function.

Stack originates in wall material resolution: packages/viewer/src/systems/wall/wall-materials.ts -> parseMaterialRef(ref) -> getLibraryMaterialIdFromRef.

  • Sentry: MONOREPO-EDITOR-EM - new (first seen 7/8), 16 events / 2 users. Catching it before it grows.

Safety

typeof x !== 'string' narrows to string, so .startsWith/.slice remain valid; return type unchanged (non-string already mapped to null). Behaviour for real string refs is identical.

Verification

tsc --noEmit on @pascal-app/core: exit 0. biome check: clean.

Opened by nightly Sentry triage. Do not auto-merge - review first.


Note

Low Risk
Narrow defensive change in core parsing; string refs unchanged, non-strings now return null instead of throwing.

Overview
Hardens getLibraryMaterialIdFromRef and getSceneMaterialIdFromRef in material-library.ts so they return null when the input is not a string, instead of calling .startsWith on numbers or other legacy/malformed wall slot values.

getSceneMaterialIdFromRef no longer relies on optional chaining alone on .startsWith; it uses the same explicit string check as the library helper. Valid string refs behave the same; parseMaterialRef and downstream wall material resolution get null instead of a runtime TypeError (Sentry MONOREPO-EDITOR-EM).

Reviewed by Cursor Bugbot for commit fde6f81. Bugbot is set up for automated code reviews on this repo. Configure here.

…ry MONOREPO-EDITOR-EM)

getLibraryMaterialIdFromRef and getSceneMaterialIdFromRef only guarded
against null/undefined, then called .startsWith(). When a non-string
material ref reaches them (legacy/malformed wall material slot ref),
.startsWith is undefined -> TypeError: e.startsWith is not a function.

Narrow with typeof !== 'string' -> return null, so a bad ref degrades to
'no library/scene material' instead of throwing during wall material
resolution (packages/viewer wall-materials.ts -> parseMaterialRef).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant