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
- Read the appended infoLog which contains the GLSL compiler's line-number diagnostics.
- 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).
- 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.
- Run the shader source through an offline glslangValidator to catch syntax before runtime.
- 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
- Pick the #version directive from ShadingLanguageVersion.
- Drop `precision highp float` from the vertex stage on contexts that reject it.
- Use GLSL ES 1.00 for WebGL1/GLES2.
- Validate offline with glslangValidator.
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
- {type} compile failed: {infoLog}
- {type} compile failed: {infoLog}
- Error compiling shader of type {type}, failed with error {in
- {name} uniform not found on shader.
- Program link failed: {infoLog}
AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13).
Data as JSON: /api/errors/ee02ac37d693b29d.
Report an issue: GitHub.