{"record":{"id":"a30e0a95345d97b4","repo":"siyuan-note/siyuan","slug":"unable-to-allocate-graph-rendering-resource","errorCode":null,"errorMessage":"Unable to allocate graph rendering resource","messagePattern":"Unable to allocate graph rendering resource","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"app/src/layout/dock/graph/webglRenderer.ts","lineNumber":508,"sourceCode":"        const gl = this.gl;\n        const shader = this.requireValue(gl.createShader(type));\n        gl.shaderSource(shader, source);\n        gl.compileShader(shader);\n        if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n            const message = gl.getShaderInfoLog(shader) || \"Unable to compile graph shader\";\n            gl.deleteShader(shader);\n            throw new Error(message);\n        }\n        return shader;\n    }\n\n    private getUniform(program: WebGLProgram, name: string) {\n        return this.requireValue(this.gl.getUniformLocation(program, name));\n    }\n\n    private requireValue<T>(value: T | null): T {\n        if (value === null) {\n            throw new Error(\"Unable to allocate graph rendering resource\");\n        }\n        return value;\n    }\n}\n","sourceCodeStart":490,"sourceCodeEnd":513,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/app/src/layout/dock/graph/webglRenderer.ts#L490-L513","documentation":"requireValue() is the null-guard wrapper around WebGL resource allocators (createProgram, createShader, createVertexArray, createBuffer, getUniformLocation). Any of them returning null trips 'Unable to allocate graph rendering resource'. WebGL functions return null when the context is lost, when the implementation refuses allocation, or when a uniform name does not exist in the program.","triggerScenarios":"The webgl2 context was lost (webglcontextlost event) but the renderer kept allocating; too many buffers/VAOs exhausted driver pools; getUniformLocation called for a uniform name that the GLSL optimizer stripped because it is unused.","commonSituations":"Tab backgrounded and the OS reclaimed the GPU context; user opened dozens of graph tabs exhausting the context pool; a uniform was renamed in GLSL but getUniform still queries the old name; driver crash mid-session.","solutions":["Add a webglcontextlost handler that sets a 'lost' flag and short-circuits requireValue so the renderer stops allocating.","Cross-check each getUniform name against the actual uniform declarations in the linked program (optimizer strips unused ones).","Tear down and recreate the renderer on webglcontextrestored, re-allocating all programs/buffers.","Reduce the number of simultaneously live WebGL contexts (one graph dock at a time)."],"exampleFix":"// before\nprivate getUniform(program: WebGLProgram, name: string) {\n    return this.requireValue(this.gl.getUniformLocation(program, name));\n}\n// after (distinguish location-missing from real alloc failure)\nprivate getUniform(program: WebGLProgram, name: string) {\n    const loc = this.gl.getUniformLocation(program, name);\n    if (!loc) throw new Error(`Uniform '${name}' not found in program (stripped by optimizer?)`);\n    return loc;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isWebGLContextLost(gl: WebGL2RenderingContext): boolean {\n    return gl.isContextLost();\n}","tryCatchPattern":"canvas.addEventListener('webglcontextlost', (e) => { e.preventDefault(); renderer?.dispose(); });\ntry { renderer = new WebGLRenderer(canvas); }\ncatch (e) { showGraphFallback(); }","preventionTips":["Handle 'webglcontextlost' to stop allocations on a dead context.","Cross-check getUniform names against the linked program; unused uniforms are stripped.","Recreate the renderer on 'webglcontextrestored'.","Limit the number of simultaneously live WebGL contexts."],"tags":["webgl","graph","resource-management","typescript"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}