{"record":{"id":"58f140060aa71eef","repo":"unoplatform/uno","slug":"program-link-failed-infolog-58f140","errorCode":null,"errorMessage":"Program link failed: {infoLog}","messagePattern":"Program link failed: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"src/SamplesApp/SamplesApp.Samples/Windows_UI_Composition/PixelBuffersGlCanvasElement.cs","lineNumber":229,"sourceCode":"\t\t\t\t2 => ((byte)0, (byte)255, x),\n\t\t\t\t3 => ((byte)0, x, (byte)255),\n\t\t\t\t4 => (x, (byte)0, (byte)255),\n\t\t\t\t_ => ((byte)255, (byte)0, x),\n\t\t\t};\n\t\t}\n\n\t\tprivate static uint CreateProgram(GL gl, string vertexSource, string fragmentSource)\n\t\t{\n\t\t\tvar vs = CompileShader(gl, ShaderType.VertexShader, vertexSource);\n\t\t\tvar fs = CompileShader(gl, ShaderType.FragmentShader, fragmentSource);\n\t\t\tvar prog = gl.CreateProgram();\n\t\t\tgl.AttachShader(prog, vs);\n\t\t\tgl.AttachShader(prog, fs);\n\t\t\tgl.LinkProgram(prog);\n\t\t\tgl.GetProgram(prog, ProgramPropertyARB.LinkStatus, out int linkStatus);\n\t\t\tif (linkStatus != (int)GLEnum.True)\n\t\t\t{\n\t\t\t\tthrow new Exception(\"Program link failed: \" + gl.GetProgramInfoLog(prog));\n\t\t\t}\n\t\t\tgl.DetachShader(prog, vs);\n\t\t\tgl.DetachShader(prog, fs);\n\t\t\tgl.DeleteShader(vs);\n\t\t\tgl.DeleteShader(fs);\n\t\t\treturn prog;\n\t\t}\n\n\t\tprivate static uint CompileShader(GL gl, ShaderType type, string source)\n\t\t{\n\t\t\tvar sh = gl.CreateShader(type);\n\t\t\tgl.ShaderSource(sh, source);\n\t\t\tgl.CompileShader(sh);\n\t\t\tgl.GetShader(sh, ShaderParameterName.CompileStatus, out int status);\n\t\t\tif (status != (int)GLEnum.True)\n\t\t\t{\n\t\t\t\tthrow new Exception($\"{type} compile failed: \" + gl.GetShaderInfoLog(sh));\n\t\t\t}","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/unoplatform/uno/blob/04183404888ea21b4e5bfa3493e8d5f15e972c3a/src/SamplesApp/SamplesApp.Samples/Windows_UI_Composition/PixelBuffersGlCanvasElement.cs#L211-L247","documentation":"CreateProgram in PixelBuffersGlCanvasElement links the vertex+fragment shader pair and throws when gl.GetProgram(LinkStatus) != GL_TRUE. Link failure means the two shaders compiled but cannot form a valid program together — the failure is almost always an interface mismatch (varying names/types, attribute locations) or a program-level limit, not a syntax problem (those surface at compile time, error 84).","triggerScenarios":"After gl.AttachShader + gl.LinkProgram on the texture-display program (vertex: aPos/aUV -> vUV; fragment: sampler2D uTex, samples texture(uTex, vUV)). GetProgram(LinkStatus) returns non-True (line 226-229). The info log from GetProgramInfoLog(prog) is appended to the message.","commonSituations":"Vertex output `out vec2 vUV` does not match fragment `in vec2 vUV` (type/location mismatch); the sampler uniform count exceeds MAX_TEXTURE_IMAGE_UNITS on constrained contexts; varying qualifiers differ (flat vs smooth); GLSL ES vs desktop GL `#version` directive mismatch between the two shader stages; both shaders compiled fine individually but reference the same attribute location with different types.","solutions":["Read the appended info log — link errors are specific ('varying vUV declared but not written', 'too many vertex attributes', etc.) and pin down the offending interface.","Confirm both shaders received the same versionDef ('#version 300 es' for GLES, '#version 330' for desktop) — a stage compiled under one profile cannot link with another profile.","Verify the vertex shader's `out` declarations exactly match the fragment shader's `in` declarations in name, type, and (on desktop) layout location.","Check attribute locations do not collide: layout(location=0) aPos and layout(location=1) aUV are distinct here, but a duplicate would link-fail.","Query MAX_TEXTURE_IMAGE_UNITS and MAX_VERTEX_ATTRIBS at Init to confirm the program's resource usage fits the context."],"exampleFix":"// before\nif (linkStatus != (int)GLEnum.True)\n    throw new Exception(\"Program link failed: \" + gl.GetProgramInfoLog(prog));\n\n// after — also surface whether each stage is currently bound/attached\nif (linkStatus != (int)GLEnum.True)\n{\n    var log = gl.GetProgramInfoLog(prog);\n    throw new Exception($\"Program link failed (vs={vs}, fs={fs}): {log}\");\n}","handlingStrategy":"validation","validationCode":"// Validate the two shaders' interfaces before linking by checking they share the same GLSL profile\nif (!vertexSource.StartsWith(versionDef) || !fragmentSource.StartsWith(versionDef))\n    throw new Exception(\"Stage GLSL profile mismatch — link will fail.\");\n// Optionally pre-link bind attribute locations to avoid collisions\ngl.BindAttribLocation(prog, 0, \"aPos\");\ngl.BindAttribLocation(prog, 1, \"aUV\");","typeGuard":null,"tryCatchPattern":"try { _program = CreateProgram(gl, vsSrc, fsSrc); }\ncatch (Exception ex) when (ex.Message.Contains(\"Program link failed\"))\n{\n    App.MainWindow?.LogError($\"Link failed; info: {ex.Message}\");\n    _program = 0; // skip rendering this element\n}","preventionTips":["Ensure vertex `out` declarations exactly match fragment `in` declarations (name, type, qualifier).","Use the same `#version` directive for both stages.","Avoid layout(location) collisions across attributes.","Query MAX_VERTEX_ATTRIBS and MAX_TEXTURE_IMAGE_UNITS to stay within limits."],"tags":["opengl","silk-net","glsl","shader-link","shader-program"],"backgroundTag":null,"analyzedSha":"04183404888ea21b4e5bfa3493e8d5f15e972c3a","analyzedAt":"2026-08-13T21:08:11.651Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}