{"record":{"id":"59c63eca1222fbbc","repo":"unoplatform/uno","slug":"name-uniform-not-found-on-shader","errorCode":null,"errorMessage":"{name} uniform not found on shader.","messagePattern":"(.+?) uniform not found on shader\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/SamplesApp/SamplesApp.Samples/Windows_UI_Composition/RotatingCubeGlCanvasElement.cs","lineNumber":200,"sourceCode":"\t\t\t\t\tthrow new Exception($\"Program failed to link with error: {_gl.GetProgramInfoLog(_handle)}\");\n\t\t\t\t}\n\t\t\t\t_gl.DetachShader(_handle, vertex);\n\t\t\t\t_gl.DetachShader(_handle, fragment);\n\t\t\t\t_gl.DeleteShader(vertex);\n\t\t\t\t_gl.DeleteShader(fragment);\n\t\t\t}\n\n\t\t\tpublic void Use()\n\t\t\t{\n\t\t\t\t_gl.UseProgram(_handle);\n\t\t\t}\n\n\t\t\tpublic void SetUniform(string name, int value)\n\t\t\t{\n\t\t\t\tint location = _gl.GetUniformLocation(_handle, name);\n\t\t\t\tif (location == -1)\n\t\t\t\t{\n\t\t\t\t\tthrow new Exception($\"{name} uniform not found on shader.\");\n\t\t\t\t}\n\t\t\t\t_gl.Uniform1(location, value);\n\t\t\t}\n\n\t\t\tpublic unsafe void SetUniform(string name, Matrix4x4 value)\n\t\t\t{\n\t\t\t\t//A new overload has been created for setting a uniform so we can use the transform in our shader.\n\t\t\t\tint location = _gl.GetUniformLocation(_handle, name);\n\t\t\t\tif (location == -1)\n\t\t\t\t{\n\t\t\t\t\tthrow new Exception($\"{name} uniform not found on shader.\");\n\t\t\t\t}\n\t\t\t\t_gl.UniformMatrix4(location, 1, false, (float*)&value);\n\t\t\t}\n\n\t\t\tpublic void SetUniform(string name, float value)\n\t\t\t{\n\t\t\t\tint location = _gl.GetUniformLocation(_handle, name);","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/unoplatform/uno/blob/04183404888ea21b4e5bfa3493e8d5f15e972c3a/src/SamplesApp/SamplesApp.Samples/Windows_UI_Composition/RotatingCubeGlCanvasElement.cs#L182-L218","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"// before\npublic void SetUniform(string name, int value)\n{\n    int location = _gl.GetUniformLocation(_handle, name);\n    if (location == -1)\n        throw new Exception($\"{name} uniform not found on shader.\");\n    _gl.Uniform1(location, value);\n}\n\n// after — cache locations, tolerate optional uniforms, log instead of throw\nprivate readonly Dictionary<string, int> _locs = new();\nprivate int Loc(string name)\n{\n    if (_locs.TryGetValue(name, out var l)) return l;\n    l = _gl.GetUniformLocation(_handle, name);\n    _locs[name] = l;\n    if (l == -1) System.Diagnostics.Debug.WriteLine($\"Uniform '{name}' inactive or missing — set ignored\");\n    return l;\n}\npublic void SetUniform(string name, int value)\n{\n    var l = Loc(name);\n    if (l != -1) _gl.Uniform1(l, value);\n}","handlingStrategy":"validation","validationCode":"// Cache locations at construction; tolerate inactive uniforms instead of throwing\nprivate readonly Dictionary<string, int> _locs = new();\npublic int Loc(string name)\n{\n    if (_locs.TryGetValue(name, out var l)) return l;\n    l = _gl.GetUniformLocation(_handle, name);\n    _locs[name] = l;\n    return l; // -1 means inactive; caller decides\n}\npublic void SetUniform(string name, int value)\n{\n    var l = Loc(name);\n    if (l != -1) _gl.Uniform1(l, value);\n}","typeGuard":null,"tryCatchPattern":"try { _shader.SetUniform(\"texUnit\", 0); }\ncatch (Exception ex) when (ex.Message.Contains(\"uniform not found\"))\n{\n    // Non-fatal: uniform inactive or misspelled\n    App.MainWindow?.LogError(ex.Message);\n}","preventionTips":["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."],"tags":["opengl","silk-net","uniform","shader-uniform","glsl","shader"],"backgroundTag":null,"analyzedSha":"04183404888ea21b4e5bfa3493e8d5f15e972c3a","analyzedAt":"2026-08-13T21:08:11.651Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}