{"record":{"id":"02f0a04e9ee6e73c","repo":"siyuan-note/siyuan","slug":"unable-to-link-graph-shader","errorCode":null,"errorMessage":"Unable to link graph shader","messagePattern":"Unable to link graph shader","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"app/src/layout/dock/graph/webglRenderer.ts","lineNumber":484,"sourceCode":"    private setViewUniforms(program: WebGLProgram, state: IGraphRenderState) {\n        this.gl.uniform2f(this.getUniform(program, \"u_viewport\"), state.width, state.height);\n        this.gl.uniform3f(this.getUniform(program, \"u_camera\"), state.camera.x, state.camera.y, state.camera.scale);\n    }\n\n    private createProgram(vertexSource: string, fragmentSource: string) {\n        const gl = this.gl;\n        const program = this.requireValue(gl.createProgram());\n        const vertex = this.createShader(gl.VERTEX_SHADER, vertexSource);\n        const fragment = this.createShader(gl.FRAGMENT_SHADER, fragmentSource);\n        gl.attachShader(program, vertex);\n        gl.attachShader(program, fragment);\n        gl.linkProgram(program);\n        gl.deleteShader(vertex);\n        gl.deleteShader(fragment);\n        if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n            const message = gl.getProgramInfoLog(program) || \"Unable to link graph shader\";\n            gl.deleteProgram(program);\n            throw new Error(message);\n        }\n        return program;\n    }\n\n    private createShader(type: number, source: string) {\n        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) {","sourceCodeStart":466,"sourceCodeEnd":502,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/app/src/layout/dock/graph/webglRenderer.ts#L466-L502","documentation":"createProgram() throws when gl.LINK_STATUS is false after gl.linkProgram. The info log (or the fallback 'Unable to link graph shader') becomes the error message. Linking fails when compiled vertex/fragment shaders are individually valid but incompatible (mismatched varying declarations, missing uniforms, or GLSL ES version inconsistencies).","triggerScenarios":"A change to the inline NODE_/EDGE_/ARROW_ shader sources breaks the vertex/fragment contract (e.g. an 'in' declared in the fragment but not 'out' in the vertex); running on a driver that rejects the program even though the sources compile; uniform name typos between getUniform lookups and shader source.","commonSituations":"Developer edits the inline GLSL in webglRenderer.ts and forgets to update both vertex and fragment pairs; a GPU driver bug refuses linking for specific feature combinations; running on older mobile GPUs with stricter linking rules.","solutions":["Inspect the thrown message — it is gl.getProgramInfoLog output and names the exact linking error.","Re-read the vertex/fragment shader pair to confirm every vertex 'out' has a matching fragment 'in' of the same type.","Verify the shaders still start with '#version 300 es' and use GLSL ES 3.00 syntax (in/out, not attribute/varying).","Reproduce on a second GPU/driver to rule out a driver-specific linker bug."],"exampleFix":"// before\nif (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n    throw new Error(gl.getProgramInfoLog(program) || 'Unable to link graph shader');\n}\n// after (surface and continue without crashing the dock)\nif (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n    console.error('shader link failed:', gl.getProgramInfoLog(program));\n    gl.deleteProgram(program);\n    showGraphFallback();\n    return null;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { return new WebGLRenderer(canvas); }\ncatch (e) {\n    console.error('graph shader link failed:', e.message);\n    showGraphFallback();\n    return null;\n}","preventionTips":["After editing GLSL, verify vertex 'out' declarations match fragment 'in' declarations exactly.","Keep the '#version 300 es' directive as the first line of every shader string.","Cross-test shader changes on more than one GPU vendor.","Log gl.getProgramInfoLog output to pinpoint the failing program."],"tags":["webgl","glsl","graph","typescript"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}