Closed bug report

3D viewer builds malformed model lookup (<slug>-board + owner:null) → intermittent PAGE_NOT_FOUND

barrett-land · 18d ago ·closed by Colby Knox

On component board pages the 3D viewer intermittently fails with:

{"error":"Page not found","code":"PAGE_NOT_FOUND","data":{"owner":null,"slug":"uv-current-monitor-board-board"}}

Two defects in the lookup the viewer constructs:

  1. Doubled -board — the real page slug is uv-current-monitor-board, but the viewer requests uv-current-monitor-board-**board** (it appends -board to a slug that already ends in -board). That page does not exist → 404.
  2. owner:null — the request drops the owner (should be adom). Even a correct slug would not resolve for a private org page with a null owner.

Intermittent: on most loads the viewer resolves the model correctly from the page's own render/board.glb and renders fine (Babylon.js v9.5.0, WebGL2). But when it takes the derive-sibling-page path it 404s, and the whole component panel (3D + schematic + deps summary) collapses to this error — which reads to the user as "no access / lots broken."

Repro: adom/uv-current-monitor-board (private, org=adom). Verified: the requested slug uv-current-monitor-board-board returns 404 with and without an owner; the real page resolves fine as adom/uv-current-monitor-board.

Fix: resolve the model from the page's own owner/slug + render assets; never send owner:null; and don't append -board when the slug already ends in it.

Reported from a live browser investigation (Firefox, signed in).

1 Reply

Colby Knox · 17d ago

Investigated end to end. The malformed lookup is not built by anything the wiki serves, and the server now self-diagnoses this request shape. Details below.

Where the -board concatenation is not (two independent sweeps, this thread and the reporting thread, so you can skip these greps):

  • git-wiki server, lib/templates.js, static/app.js, the vendored 3D viewer bundle (20260717e), and symview viewer-gen.js: no code anywhere appends -board or derives sibling page slugs.
  • The Babylon fork (adom-3d-viewer-babylon9): zero slug/owner/page-API logic; the bundle only loads the modelUrl it is handed.
  • This page's custom viewer slots: adom/uv-current-monitor-board declares none (component.viewers is absent).
  • The live page markup, fetched signed in: exactly one viewer surface, the owner-qualified iframe /viewer/3d/adom/component/uv-current-monitor-board, zero board-board strings, and no client-side page fetches at all. The wiki page is server-rendered and cannot produce this request or collapse from its failure.

So the code that builds <slug>-board with no owner runs outside the wiki: whatever rendered the panel you were looking at (an editor-side Hydrogen panel or agent tooling that consumes render/manifest.json). Knowing which app rendered that panel would pin the fix location immediately; please reply with that if you can.

What the client needs to change (wherever it lives):

  1. Never derive a sibling slug by appending -board to a name that already ends in it.
  2. Always pass the page's own owner and slug; an ownerless lookup can never resolve a private org page.
  3. Treat the page's own render assets (render/board.glb per render/manifest.json) as authoritative and only derive a sibling when the page has none; a 404 on the derive path should degrade to hiding the 3D pane, not collapse the whole panel.

What shipped on the server (live on prod now): PAGE_NOT_FOUND responses self-diagnose this exact mistake. The guidance derives only from the requested string, never the database, so the no-existence-oracle invariant holds (missing and private stay identical). Your original request now returns:

GET /api/pages/uv-current-monitor-board-board/files/render/board.glb
{
  "error": "Page not found",
  "hint": "No such page, or it's private and you don't have access. The requested
    slug ends in a doubled \"-board\": clients that derive sibling slugs by
    appending \"-board\" to a base name produce this when the base already ends
    in it. You may have meant \"uv-current-monitor-board\". No owner in the path:
    private org pages never resolve on the bare-slug route, use
    /api/pages/<owner>/<slug>.",
  "code": "PAGE_NOT_FOUND",
  "data": { "owner": null, "slug": "uv-current-monitor-board-board",
            "suggested_slug": "uv-current-monitor-board" }
}

data.suggested_slug is machine-readable so a client can self-correct without parsing prose. The guidance is uniform across the page GET routes, every read-gated page verb, and the files route.

Also checked the related shadowing concern: the viewer routes are owner-qualified on current prod (/viewer/3d/:owner/:type/:slug, and viewerPath builds every iframe URL with the owner); the bare forms remain only for legacy pages and carry collision markers.

Closing since the server side is complete and the remaining defects live in the client that constructed the request. Reopen or reply with the name of the app that rendered the panel and we will route the fix to the right repo.

This comment was deleted by its author · 17d ago

Log in to reply.