{"record":{"id":"ae13bc863320cf8c","repo":"unoplatform/uno","slug":"program-link-failed-infolog-ae13bc","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/QuerySyncGlCanvasElement.cs","lineNumber":279,"sourceCode":"\t\t\t// --- Fence this frame's commands and kick the GPU ---\n\t\t\t_frameSync = gl.FenceSync(SyncCondition.SyncGpuCommandsComplete, (SyncBehaviorFlags)0);\n\t\t\tgl.Flush();\n\n\t\t\tInvalidate();\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":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/unoplatform/uno/blob/04183404888ea21b4e5bfa3493e8d5f15e972c3a/src/SamplesApp/SamplesApp.Samples/Windows_UI_Composition/QuerySyncGlCanvasElement.cs#L261-L297","documentation":"CreateProgram in QuerySyncGlCanvasElement links the bars and probe shader pairs and throws when link status is not True. Same mechanism as errors 83 and 86; here it applies to _barsProgram (instanced bars, uWave[8] + uPalette[4] uniforms) and _probeProgram (uRect vec4 + uColor vec4 uniforms).","triggerScenarios":"After AttachShader + LinkProgram for either the bars program or the probe program, gl.GetProgram(LinkStatus) != True (lines 276-279). The info log is appended.","commonSituations":"Bars vertex shader outputs `out vec3 vColor` while fragment declares `in vec3 vColor` (these match, but a typo would link-fail); the probe vertex shader has no `out` and the probe fragment has no `in` so the interface is trivially empty — a link failure here usually means a stage-level issue like too many uniform components (uWave[8] + uPalette[12] floats may approach per-stage uniform limits on low-end contexts); versionDef mismatch between the bars VS and bars FS; array uniform declaration mismatch between stages.","solutions":["Read the appended info log to find the specific unresolved interface or exceeded limit.","Confirm both stages of the failing program received the same versionDef.","Check the bars program's total uniform component count (uWave = 8 floats, uPalette = 12 floats) against gl.Get(MAX_VERTEX_UNIFORM_COMPONENTS) — low-end GLES contexts may have limits around 256-1024.","Verify the vertex `out`/fragment `in` declarations match exactly (name + type) for the bars program.","Link bars and probe programs separately and report which one failed."],"exampleFix":"// before\nif (linkStatus != (int)GLEnum.True)\n    throw new Exception(\"Program link failed: \" + gl.GetProgramInfoLog(prog));\n\n// after — name the failing program in the message\nif (linkStatus != (int)GLEnum.True)\n    throw new Exception($\"Program link failed (caller: {new System.Diagnostics.StackFrame(1).GetMethod().Name}): {gl.GetProgramInfoLog(prog)}\");","handlingStrategy":"validation","validationCode":"// Confirm both stages share versionDef and that uniform component count fits limits\nif (!vertexSource.StartsWith(versionDef) || !fragmentSource.StartsWith(versionDef)) return;\ngl.GetInteger(GetPName.MaxVertexUniformComponents, out int maxVertUniforms);\n// bars program: uWave(8) + uPalette(12) = 20 floats — well under typical 1024+ limit\nif (maxVertUniforms < 32) return; // tight context; link may fail","typeGuard":null,"tryCatchPattern":"try { _barsProgram = CreateProgram(gl, barsVs, barsFs); }\ncatch (Exception ex) when (ex.Message.Contains(\"Program link failed\"))\n{\n    App.MainWindow?.LogError($\"Bars program link failed: {ex.Message}\");\n    _barsProgram = 0;\n}","preventionTips":["Match vertex `out` and fragment `in` declarations exactly.","Use the same GLSL profile across both stages.","Check MAX_VERTEX_UNIFORM_COMPONENTS for array-heavy programs.","Link bars and probe programs separately to localize failures."],"tags":["opengl","silk-net","glsl","shader-link","shader-program","uniform-array"],"backgroundTag":null,"analyzedSha":"04183404888ea21b4e5bfa3493e8d5f15e972c3a","analyzedAt":"2026-08-13T21:08:11.651Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}