unoplatform/uno · error · Exception
{name} uniform not found on shader.
Error message
{name} uniform not found on shader. What it means
The int overload of Shader.SetUniform in RotatingCubeGlCanvasElement looks up a uniform by name and throws if gl.GetUniformLocation returns -1. A -1 means the uniform does not exist in the linked program — either the name is misspelled, the uniform was declared but optimized out by the compiler, or the wrong program is bound.
Source
Thrown at src/SamplesApp/SamplesApp.Samples/Windows_UI_Composition/RotatingCubeGlCanvasElement.cs:200
throw new Exception($"Program failed to link with error: {_gl.GetProgramInfoLog(_handle)}");
}
_gl.DetachShader(_handle, vertex);
_gl.DetachShader(_handle, fragment);
_gl.DeleteShader(vertex);
_gl.DeleteShader(fragment);
}
public void Use()
{
_gl.UseProgram(_handle);
}
public void SetUniform(string name, int value)
{
int location = _gl.GetUniformLocation(_handle, name);
if (location == -1)
{
throw new Exception($"{name} uniform not found on shader.");
}
_gl.Uniform1(location, value);
}
public unsafe void SetUniform(string name, Matrix4x4 value)
{
//A new overload has been created for setting a uniform so we can use the transform in our shader.
int location = _gl.GetUniformLocation(_handle, name);
if (location == -1)
{
throw new Exception($"{name} uniform not found on shader.");
}
_gl.UniformMatrix4(location, 1, false, (float*)&value);
}
public void SetUniform(string name, float value)
{
int location = _gl.GetUniformLocation(_handle, name);View on GitHub (pinned to 0418340488)
Solutions
- Confirm the uniform name matches a declared, used uniform in the shader source — for the cube, only `transform` exists, so int-typed SetUniform calls are inherently invalid.
- Use the uniform in the shader body so the compiler keeps it active; an unused uniform is pruned and returns -1 by spec.
- Cache uniform locations at construction time (after link) rather than looking them up per-call, so a missing uniform fails fast at Init with context, not at render time.
- Downgrade the throw to a no-op + log if the uniform is optional, since GetUniformLocation returning -1 for an inactive uniform is defined behavior, not an error.
- Verify the program was linked successfully (error 95) before any SetUniform call — a failed link leaves _handle in an unusable state.
Example fix
// before
public void SetUniform(string name, int value)
{
int location = _gl.GetUniformLocation(_handle, name);
if (location == -1)
throw new Exception($"{name} uniform not found on shader.");
_gl.Uniform1(location, value);
}
// after — cache locations, tolerate optional uniforms, log instead of throw
private readonly Dictionary<string, int> _locs = new();
private int Loc(string name)
{
if (_locs.TryGetValue(name, out var l)) return l;
l = _gl.GetUniformLocation(_handle, name);
_locs[name] = l;
if (l == -1) System.Diagnostics.Debug.WriteLine($"Uniform '{name}' inactive or missing — set ignored");
return l;
}
public void SetUniform(string name, int value)
{
var l = Loc(name);
if (l != -1) _gl.Uniform1(l, value);
} Defensive patterns
Strategy: validation
Validate before calling
// Cache locations at construction; tolerate inactive uniforms instead of throwing
private readonly Dictionary<string, int> _locs = new();
public int Loc(string name)
{
if (_locs.TryGetValue(name, out var l)) return l;
l = _gl.GetUniformLocation(_handle, name);
_locs[name] = l;
return l; // -1 means inactive; caller decides
}
public void SetUniform(string name, int value)
{
var l = Loc(name);
if (l != -1) _gl.Uniform1(l, value);
} Try / catch
try { _shader.SetUniform("texUnit", 0); }
catch (Exception ex) when (ex.Message.Contains("uniform not found"))
{
// Non-fatal: uniform inactive or misspelled
App.MainWindow?.LogError(ex.Message);
} Prevention
- Confirm the uniform name matches a declared AND used uniform in the GLSL.
- Cache locations at construction so failures surface at Init with context.
- Tolerate GetUniformLocation returning -1 for inactive uniforms (defined behavior).
- Verify the program linked successfully before SetUniform.
When it happens
Trigger: Inside SetUniform(string name, int value): _gl.GetUniformLocation(_handle, name) == -1 (lines 197-200). The cube shader only declares one uniform (`mat4 transform`), so any int-typed SetUniform call would inherently hit this — there is no `int` uniform declared in the shader source.
Common situations: Calling SetUniform with a uniform name that is not declared in the GLSL (e.g. an int sampler name when only `transform` exists); the uniform was declared but unused, so the GLSL compiler pruned it and GetUniformLocation legitimately returns -1 (this is defined behavior, not a bug); typo in the name; the program was not linked / linked unsuccessfully; calling SetUniform before Use() (location lookup does not require Use, but a stale _handle would).
Related errors
- {type} compile failed: {infoLog}
- {type} compile failed: {infoLog}
- GetUniform readback mismatch: got {firstComponent}, expected
- GetActiveUniform did not report uWave[{BarCount}] (saw {acti
- {type} compile failed: {infoLog}
AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13).
Data as JSON: /api/errors/59c63eca1222fbbc.
Report an issue: GitHub.