unoplatform/uno · critical · Exception

Program link failed: {infoLog}

Error message

Program link failed: {infoLog}

What it means

CreateProgram in PostProcessGlCanvasElement links the scene and post-process shader pairs and throws when the link status is not True. Identical mechanism to error 83 but applies to the two programs that drive the rotating-triangle scene pass and the displacement-sampling post pass.

Source

Thrown at src/SamplesApp/SamplesApp.Samples/Windows_UI_Composition/PostProcessGlCanvasElement.cs:213

			gl.Uniform1(_postUTimeLoc, t);
			gl.BindVertexArray(_postVao);
			gl.DrawArrays(PrimitiveType.Triangles, 0, 6);

			Invalidate();
		}

		private static uint CreateProgram(GL gl, string vertexSource, string fragmentSource)
		{
			var vs = CompileShader(gl, ShaderType.VertexShader, vertexSource);
			var fs = CompileShader(gl, ShaderType.FragmentShader, fragmentSource);
			var prog = gl.CreateProgram();
			gl.AttachShader(prog, vs);
			gl.AttachShader(prog, fs);
			gl.LinkProgram(prog);
			gl.GetProgram(prog, ProgramPropertyARB.LinkStatus, out int linkStatus);
			if (linkStatus != (int)GLEnum.True)
			{
				throw new Exception("Program link failed: " + gl.GetProgramInfoLog(prog));
			}
			gl.DetachShader(prog, vs);
			gl.DetachShader(prog, fs);
			gl.DeleteShader(vs);
			gl.DeleteShader(fs);
			return prog;
		}

		private static uint CompileShader(GL gl, ShaderType type, string source)
		{
			var sh = gl.CreateShader(type);
			gl.ShaderSource(sh, source);
			gl.CompileShader(sh);
			gl.GetShader(sh, ShaderParameterName.CompileStatus, out int status);
			if (status != (int)GLEnum.True)
			{
				throw new Exception($"{type} compile failed: " + gl.GetShaderInfoLog(sh));
			}

View on GitHub (pinned to 0418340488)

Solutions

  1. Read the appended GetProgramInfoLog output — it names the unresolved varying or the exceeded limit.
  2. Verify the vertex `out` and fragment `in` blocks match exactly (name, type, qualifier) for the failing program.
  3. Confirm both stages use the same versionDef so the GLSL profiles match.
  4. Check that the number of active samplers (here just uTex, one) is within MAX_TEXTURE_IMAGE_UNITS.
  5. Link one program at a time and isolate which of _sceneProgram / _postProgram fails to localize the interface mismatch.

Example fix

// before
if (linkStatus != (int)GLEnum.True)
    throw new Exception("Program link failed: " + gl.GetProgramInfoLog(prog));

// after — tag which program (scene vs post) failed
if (linkStatus != (int)GLEnum.True)
    throw new Exception($"Program link failed [vs={Path.GetFileName(vertexSource.GetHashCode().ToString())}]: {gl.GetProgramInfoLog(prog)}");
Defensive patterns

Strategy: validation

Validate before calling

// Confirm both stages share the versionDef and that varyings match
if (!vertexSource.StartsWith(versionDef) || !fragmentSource.StartsWith(versionDef)) return;
// Pre-link: bind attrib locations explicitly to avoid collisions
gl.BindAttribLocation(prog, 0, "aPos");
gl.BindAttribLocation(prog, 1, "aColor"); // or aUV

Try / catch

try { _sceneProgram = CreateProgram(gl, sceneVs, sceneFs); }
catch (Exception ex) when (ex.Message.Contains("Program link failed"))
{
    App.MainWindow?.LogError($"Scene program link failed: {ex.Message}");
    _sceneProgram = 0;
}

Prevention

When it happens

Trigger: After AttachShader(vertex) + AttachShader(fragment) + LinkProgram for either _sceneProgram (aPos/aColor in, uTime uniform, vColor out) or _postProgram (aPos/aUV in, uTex sampler + uTime uniform, vUV out). GetProgram(LinkStatus) != True (lines 210-213).

Common situations: The scene vertex shader outputs `out vec3 vColor` while the fragment declares `in vec3 vColor` — a type/name mismatch link-fails; the post fragment shader declares `uniform sampler2D uTex` but the sampler's texture unit binding is invalid in the current context (link-time, not run-time, if the sampler count exceeds limits); versionDef mismatch between stages; both programs share the same attribute locations which is fine individually but a per-program link fails if layout(location) qualifiers collide with built-in attribs on some drivers.

Related errors


AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13). Data as JSON: /api/errors/7000d550577af19e. Report an issue: GitHub.