unoplatform/uno · critical · Exception

{type} compile failed: {infoLog}

Error message

{type} compile failed: {infoLog}

What it means

CompileShader in PostProcessGlCanvasElement throws when a stage fails to compile, before the program is linked (error 86). The info log is appended. Applies to both the scene vertex/fragment sources and the post-process vertex/fragment sources.

Source

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

			{
				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));
			}
			return sh;
		}
	}
}
#endif

View on GitHub (pinned to 0418340488)

Solutions

  1. Read the appended infoLog which contains the GLSL compiler's line-number diagnostics.
  2. Print gl.GetStringS(StringName.ShadingLanguageVersion) and confirm the versionDef matches (the sample already does this check at lines 99-102 — verify it ran before the throw).
  3. For WebGL1/GLES2 contexts, fall back to GLSL ES 1.00 syntax: replace in/out with attribute/varying, gl_FragData[0] or gl_FragColor, and drop layout qualifiers.
  4. Run the shader source through an offline glslangValidator to catch syntax before runtime.
  5. If `precision highp float` is the offender on the vertex stage, move precision declarations to the fragment stage only or downgrade to mediump.

Example fix

// before
if (status != (int)GLEnum.True)
    throw new Exception($"{type} compile failed: " + gl.GetShaderInfoLog(sh));

// after — include the offending source with line numbers
if (status != (int)GLEnum.True)
{
    var log = gl.GetShaderInfoLog(sh);
    var src = string.Join('\n', source.Split('\n').Select((l, i) => $"{i+1,3}: {l}"));
    throw new Exception($"{type} compile failed: {log}\n{src}");
}
Defensive patterns

Strategy: validation

Validate before calling

var sl = gl.GetStringS(StringName.ShadingLanguageVersion);
var gles = sl.Contains("OpenGL ES", StringComparison.OrdinalIgnoreCase);
if (gles && !sl.Contains("3.")) return; // #version 300 es not supported
if (!source.StartsWith(gles ? "#version 300 es" : "#version 330")) return;

Try / catch

try { sh = CompileShader(gl, type, source); }
catch (Exception ex) when (ex.Message.Contains("compile failed"))
{
    App.MainWindow?.LogError($"{type} compile failed (PostProcess): {ex.Message}");
    sh = 0;
}

Prevention

When it happens

Trigger: Inside CompileShader after gl.CreateShader + ShaderSource + CompileShader, gl.GetShader(CompileStatus) != True (lines 223-230). The scene fragment shader uses `in vec3 vColor; out vec4 fragColor;` and the post fragment shader uses sine-wave displacement and samples uTex.

Common situations: versionDef picked the wrong GLSL profile for the running context (desktop `#version 330` on a GLES context); `precision highp float` rejected on the vertex stage of a low-end context; layout(location=0) qualifiers unsupported on GLSL ES 1.00; a typo in the displacement math (e.g. an undeclared identifier); the sine `mat2 rot = mat2(c, -s, s, c)` construct rejected on a context that lacks the constructor overload.

Related errors


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