Version
codebase-memory-mcp 0.8.1 (darwin-arm64, ui variant)
Platform
macOS 26.5.1 (Apple M5 Pro), Brave + Chrome. Reproduces on any Chromium browser when the window is large / on a high-DPI display.
What happened
Clicking View Graph shows the Graph tab with the correct sidebar, filters, and node/edge counts (e.g. 2,648 nodes / 5,095 edges), but the 3D canvas is entirely black. No UI error, ErrorBoundary does not trigger. Same black-canvas symptom as the (closed) #453, but a different root cause — see below.
Root cause (confirmed via chrome://gpu log)
The post-processing pipeline (EffectComposer + RenderPass, present in the served bundle) creates a multisampled render target sized to the canvas backing store, which is cssSize × devicePixelRatio. The bundle calls renderer.setPixelRatio(dpr) with the uncapped device DPR. On a large, high-DPI display the multisampled renderbuffer exceeds the GPU's max allocation:
GL_INVALID_OPERATION: glRenderbufferStorageMultisample: Texture total allocation size is too large.
GL_INVALID_FRAMEBUFFER_OPERATION: glClear: Framebuffer is incomplete: Attachment has zero size.
GL_INVALID_FRAMEBUFFER_OPERATION: glDrawElementsInstanced: Framebuffer is incomplete: Attachment has zero size.
Because the MSAA renderbuffer allocation fails, the composer's framebuffer attachment ends up zero-sized, every subsequent glClear/glDrawElementsInstanced/glBlitFramebuffer targets an incomplete framebuffer, and nothing is drawn → black canvas. The MCP server, the data, and plain WebGL2 are all fine (a WebGL1 test page renders a cube normally).
GPU context from the log:
GL_RENDERER: ANGLE (Apple, ANGLE Metal Renderer: Apple M5 Pro)
Max. MSAA samples: 8
- Displays: internal
1800x1169 @ scale 2, external 2560x1440 @ scale 2, external 3200x1800 @ scale 2
Reproduction
- Index any repo and open the graph UI on a high-DPI display (devicePixelRatio = 2).
- Maximize the browser window on a large/high-res monitor.
- Click View Graph → black canvas;
chrome://gpu Log Messages show glRenderbufferStorageMultisample: Texture total allocation size is too large.
- Workaround that confirms the cause: shrink the window (or
Cmd - zoom out, or move to a lower-res display) and reload → the graph renders. This proves it is the canvas/render-target size, not Shields/CDN/data.
Suggested fix
Cap the renderer pixel ratio for the WebGL canvas / composer, e.g.:
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 1.5))
or, more robustly, clamp the composer's render-target dimensions to gl.getParameter(gl.MAX_RENDERBUFFER_SIZE) (and to a sane total-bytes budget), and/or fall back to antialias: false / samples: 0 on the composer when the would-be allocation exceeds the limit. R3F's <Canvas dpr={[1, 1.5]}> is the one-line equivalent.
Bonus: when glRenderbufferStorageMultisample fails, surface it through the ErrorBoundary instead of silently rendering black.
Version
codebase-memory-mcp 0.8.1 (darwin-arm64,
uivariant)Platform
macOS 26.5.1 (Apple M5 Pro), Brave + Chrome. Reproduces on any Chromium browser when the window is large / on a high-DPI display.
What happened
Clicking View Graph shows the Graph tab with the correct sidebar, filters, and node/edge counts (e.g.
2,648 nodes / 5,095 edges), but the 3D canvas is entirely black. No UI error,ErrorBoundarydoes not trigger. Same black-canvas symptom as the (closed) #453, but a different root cause — see below.Root cause (confirmed via
chrome://gpulog)The post-processing pipeline (
EffectComposer+RenderPass, present in the served bundle) creates a multisampled render target sized to the canvas backing store, which iscssSize × devicePixelRatio. The bundle callsrenderer.setPixelRatio(dpr)with the uncapped device DPR. On a large, high-DPI display the multisampled renderbuffer exceeds the GPU's max allocation:Because the MSAA renderbuffer allocation fails, the composer's framebuffer attachment ends up zero-sized, every subsequent
glClear/glDrawElementsInstanced/glBlitFramebuffertargets an incomplete framebuffer, and nothing is drawn → black canvas. The MCP server, the data, and plain WebGL2 are all fine (a WebGL1 test page renders a cube normally).GPU context from the log:
GL_RENDERER: ANGLE (Apple, ANGLE Metal Renderer: Apple M5 Pro)Max. MSAA samples: 81800x1169 @ scale 2, external2560x1440 @ scale 2, external3200x1800 @ scale 2Reproduction
chrome://gpuLog Messages showglRenderbufferStorageMultisample: Texture total allocation size is too large.Cmd -zoom out, or move to a lower-res display) and reload → the graph renders. This proves it is the canvas/render-target size, not Shields/CDN/data.Suggested fix
Cap the renderer pixel ratio for the WebGL canvas / composer, e.g.:
or, more robustly, clamp the composer's render-target dimensions to
gl.getParameter(gl.MAX_RENDERBUFFER_SIZE)(and to a sane total-bytes budget), and/or fall back toantialias: false/samples: 0on the composer when the would-be allocation exceeds the limit. R3F's<Canvas dpr={[1, 1.5]}>is the one-line equivalent.Bonus: when
glRenderbufferStorageMultisamplefails, surface it through theErrorBoundaryinstead of silently rendering black.