{"record":{"id":"7f4d655398fde5ae","repo":"unoplatform/uno","slug":"validateprogram-failed-infolog","errorCode":null,"errorMessage":"ValidateProgram failed: {infoLog}","messagePattern":"ValidateProgram failed: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/SamplesApp/SamplesApp.Samples/Windows_UI_Composition/QuerySyncGlCanvasElement.cs","lineNumber":157,"sourceCode":"\n\t\t\t// Program introspection: enumerate active uniforms and validate the program.\n\t\t\tgl.GetProgram(_barsProgram, ProgramPropertyARB.ActiveUniforms, out int activeUniforms);\n\t\t\tvar foundWave = false;\n\t\t\tfor (uint i = 0; i < activeUniforms; i++)\n\t\t\t{\n\t\t\t\tvar name = gl.GetActiveUniform(_barsProgram, i, out int size, out UniformType type);\n\t\t\t\t// Array uniforms report as \"uWave[0]\" with size = element count.\n\t\t\t\tfoundWave |= name.StartsWith(\"uWave\", StringComparison.Ordinal) && size == BarCount && type == UniformType.Float;\n\t\t\t}\n\t\t\tif (!foundWave)\n\t\t\t{\n\t\t\t\tthrow new Exception($\"GetActiveUniform did not report uWave[{BarCount}] (saw {activeUniforms} active uniforms)\");\n\t\t\t}\n\t\t\tgl.ValidateProgram(_barsProgram);\n\t\t\tgl.GetProgram(_barsProgram, ProgramPropertyARB.ValidateStatus, out int validateStatus);\n\t\t\tif (validateStatus != (int)GLEnum.True)\n\t\t\t{\n\t\t\t\tthrow new Exception(\"ValidateProgram failed: \" + gl.GetProgramInfoLog(_barsProgram));\n\t\t\t}\n\n\t\t\t_query = gl.GenQuery();\n\n\t\t\t// Init must finish error-clean; surface anything the calls above raised.\n\t\t\tvar err = gl.GetError();\n\t\t\tif (err != GLEnum.NoError)\n\t\t\t{\n\t\t\t\tthrow new Exception($\"GL error at end of Init: 0x{(int)err:x}\");\n\t\t\t}\n\t\t}\n\n\t\tprotected override void OnDestroy(GL gl)\n\t\t{\n\t\t\tgl.DeleteVertexArray(_barsVao);\n\t\t\tgl.DeleteVertexArray(_probeVao);\n\t\t\tgl.DeleteBuffer(_quadVbo);\n\t\t\tgl.DeleteProgram(_barsProgram);","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/unoplatform/uno/blob/04183404888ea21b4e5bfa3493e8d5f15e972c3a/src/SamplesApp/SamplesApp.Samples/Windows_UI_Composition/QuerySyncGlCanvasElement.cs#L139-L175","documentation":"gl.ValidateProgram checks whether _barsProgram can execute given the current GL state (sampler bindings, bound VAO, etc.) and writes VALIDATE_STATUS. A failed validation means the program would behave incorrectly or undefined in the current state — distinct from link status which only checks the program object in isolation. This sample validates at Init time as a self-check.","triggerScenarios":"After gl.ValidateProgram(_barsProgram) and gl.GetProgram(ValidateStatus, out validateStatus), validateStatus != (int)GLEnum.True (lines 153-157). The info log is appended.","commonSituations":"ValidateProgram runs against the current state — at this Init point no sampler textures are bound (uWave is a float array, uPalette is a vec3 array, so no samplers in _barsProgram, which is good), but if a sampler-type uniform existed without a bound texture unit the validation would fail; the current VAO/program state at validation time differs from render time; on some drivers ValidateProgram is stricter than actual execution and flags benign issues; the program was linked but with unresolved samplers.","solutions":["Read the appended info log — validation errors are specific ('Sampler uTex not bound to a texture unit', 'Validation differs from current state').","Ensure the GL state at ValidateProgram time matches what Render will use: bind the program, set any sampler-to-texture-unit mappings, before validating.","Treat ValidateProgram as advisory on some drivers (Apple, ANGLE) — if the program actually renders correctly, consider downgrading this throw to a logged warning.","If the validation complains about a sampler, add the ActiveTexture + BindTexture + Uniform1(samplerLoc, unitIndex) sequence before ValidateProgram.","Confirm _barsProgram is the currently bound program (UseProgram was called at line 132) before validating."],"exampleFix":"// before\ngl.ValidateProgram(_barsProgram);\ngl.GetProgram(_barsProgram, ProgramPropertyARB.ValidateStatus, out int validateStatus);\nif (validateStatus != (int)GLEnum.True)\n    throw new Exception(\"ValidateProgram failed: \" + gl.GetProgramInfoLog(_barsProgram));\n\n// after — validate in the same state Render uses, log as warning if advisory-only\ngl.UseProgram(_barsProgram);\ngl.BindVertexArray(_barsVao);\ngl.ValidateProgram(_barsProgram);\ngl.GetProgram(_barsProgram, ProgramPropertyARB.ValidateStatus, out int validateStatus);\nif (validateStatus != (int)GLEnum.True)\n{\n    var log = gl.GetProgramInfoLog(_barsProgram);\n    // Some drivers (ANGLE/Apple) flag advisory issues; keep rendering if the log is non-fatal.\n    System.Diagnostics.Debug.WriteLine($\"ValidateProgram advisory: {log}\");\n}","handlingStrategy":"validation","validationCode":"// Validate in the same state Render will use, before checking\ngl.UseProgram(_barsProgram);\ngl.BindVertexArray(_barsVao);\ngl.ValidateProgram(_barsProgram);\ngl.GetProgram(_barsProgram, ProgramPropertyARB.ValidateStatus, out int validateStatus);\n// Treat as advisory on drivers known to over-flag (ANGLE, Apple)","typeGuard":null,"tryCatchPattern":"try { /* ValidateProgram check */ }\ncatch (Exception ex) when (ex.Message.Contains(\"ValidateProgram failed\"))\n{\n    // Non-fatal: validation is advisory on many drivers\n    App.MainWindow?.LogError($\"ValidateProgram advisory: {ex.Message}\");\n}","preventionTips":["Bind the program and any sampler/VAO state before ValidateProgram so the check reflects render-time state.","Treat ValidateProgram as advisory on ANGLE/Apple drivers that over-flag.","Read the info log for the specific validation complaint.","If validation complains about a sampler, set the sampler-to-texture-unit binding before validating."],"tags":["opengl","silk-net","shader-program","validate-program","shader-state","glsl"],"backgroundTag":null,"analyzedSha":"04183404888ea21b4e5bfa3493e8d5f15e972c3a","analyzedAt":"2026-08-13T21:08:11.651Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}