Skip to content

Graph UI: embedded UI makes runtime CDN requests via troika-three-text, breaks rendering when CDN is blocked #453

Description

@kortschak

Version

codebase-memory-mcp 0.8.1

Platform

Linux (x64)

Install channel

GitHub release archive / install.sh / install.ps1

Binary variant

ui

What happened, and what did you expect?

The graph UI loads and the Projects tab shows indexed projects with correct node/edge counts. Clicking "View Graph" switches to the Graph tab, but the 3D canvas is entirely black. No error message is shown in the UI; the ErrorBoundary does not trigger.

Expected: the 3D graph renders with nodes and edges. The embedded UI binary should be self-contained with no runtime CDN dependencies.

Reproduction

  1. Install the ui binary variant on Linux x64.
  2. Enable the UI: codebase-memory-mcp --ui=true
  3. Index any repository (the specific project does not matter).
  4. Open http://127.0.0.1:9749 in a browser where cdn.jsdelivr.net is blocked (e.g. a browser extension that restricts outbound requests, a corporate firewall, or an air-gapped environment).
  5. Go to the Projects tab, confirm the project appears with stats.
  6. Click "View Graph".
  7. The graph pane is black. The browser console shows:
Content-Security-Policy: The report URI (about:blank) should be an HTTP or HTTPS URI.
Content-Security-Policy: (Report-Only policy) The page's settings would block a worker script (worker-src) at blob:http://localhost:9749/bc03070d-bab9-4d51-adb0-124f47665b8f from being executed because it violates the following directive: "worker-src 'none'"
TypeError: NetworkError when attempting to fetch resource.
  1. Allow cdn.jsdelivr.net in the browser → the graph renders correctly.
  2. Alternatively, open the same URL in a browser with no restrictions → the graph renders correctly.

Discovered using uMatrix in the Zen browser (Firefox-based). When uMatrix blocks the jsdelivr CDN fetch, the rendering fails. Allowing cdn.jsdelivr.net in uMatrix resolves the problem without any other changes.

Root cause

The Text component from @react-three/drei (used in graph-ui/src/components/NodeLabels.tsx) uses troika-three-text under the hood. troika-three-text fetches its default font and unicode-font-resolver data from cdn.jsdelivr.net at runtime. When this CDN is unreachable (blocked by extension, firewall, or air-gap), the font fetch fails. This failure cascades into the Three.js rendering pipeline; the EffectComposer/Bloom post-processing captures the scene into an offscreen framebuffer, but the failure prevents the final composite-to-screen step, resulting in a black canvas with no React-level error.

The embedded UI binary should be fully self-contained. A runtime dependency on an external CDN contradicts that.

Suggested fix

Bundle a font file into the Vite build and pass it via the font prop on the <Text> component in NodeLabels.tsx. This eliminates the runtime CDN fetch. For example:

import interFont from "../assets/Inter-Medium.woff2?url";

<Text font={interFont} ...>

Alternatively, use troika-three-text's configureTextBuilder to point unicodeFontsURL at a local asset path.

The EffectComposer/Bloom could also benefit from graceful degradation; if the post-processing pipeline fails for any reason, the scene should still render directly to the screen without effects rather than showing a black canvas.

Logs

No server-side errors. The failure is entirely client-side. The runtime fetch to `cdn.jsdelivr.net` fails and the rendering pipeline breaks silently.

Project scale (if relevant)

13,314 nodes / 48,950 edges / 530 files

Confirmations

  • I searched existing issues and this is not a duplicate.
  • My reproduction uses shareable code (a dummy snippet or a public OSS repository), not proprietary code.

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

    bugSomething isn't workingsecuritySecurity vulnerabilities, hardeningux/behaviorDisplay bugs, docs, adoption UX

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions