BabylonJS/Babylon.js · error
Shader bindings not set!
Error message
Shader bindings not set!
What it means
OptimizedShaderBlock defers creation of its ShaderBinding until bindings are set during optimization (this._shaderBindings). getShaderBinding() throws this error if called before the optimizer has populated them, because there is no object available to bind uniforms/textures to the effect.
Source
Thrown at packages/dev/smartFilters/src/optimization/optimizedShaderBlock.ts:114
public setShaderProgram(shaderProgram: ShaderProgram): void {
this._shaderProgram = shaderProgram;
}
/**
* Sets the list of shader bindings to use to render the block.
* @param shaderBindings - The list of shader bindings to use to render the block
*/
public setShaderBindings(shaderBindings: ShaderBinding[]): void {
this._shaderBindings = shaderBindings;
}
/**
* Get the class instance that binds all the required data to the shader (effect) when rendering.
* @returns The class instance that binds the data to the effect
*/
public getShaderBinding(): ShaderBinding {
if (this._shaderBindings === null) {
throw new Error("Shader bindings not set!");
}
for (const input of this.inputs) {
const name = input.name;
if (input.type === ConnectionPointType.Texture) {
/**
* These are the inputs created by the OptimizedShaderBlock
* We pass them to OptimizedShaderBinding so that their value can be set appropriately at runtime (in the bind method)
*/
this._inputTextures[name] = input.runtimeData as RuntimeData<ConnectionPointType.Texture>;
}
}
return new OptimizedShaderBinding(this._shaderBindings, this._inputTextures);
}
}
View on GitHub (pinned to 0592b347b8)
Solutions
- Run SmartFilterOptimizer (or the standard filter build) to populate shader bindings before rendering.
- Ensure the previous optimization step did not throw and leave the block partially optimized.
- Only render/execute optimized filters through the SmartFilter runtime rather than calling getShaderBinding manually.
Example fix
// before const binding = optimizedBlock.getShaderBinding(); // too early // after const runtimeData = await SmartFilterOptimizer.OptimizeAsync(engine, smartFilter, texture); // runtime data is now bound; use runtimeData to render
Defensive patterns
Strategy: validation
Validate before calling
if (!optimizedBlock["_shaderBindings"]) {
throw new Error("Run SmartFilterOptimizer before accessing shader bindings");
} Type guard
null
Try / catch
try {
const binding = optimizedBlock.getShaderBinding();
} catch (e) {
if (e.message === "Shader bindings not set!") {
throw new Error("Filter must be optimized via SmartFilterOptimizer before rendering");
} else throw e;
} Prevention
- Always create optimized blocks through SmartFilterOptimizer, never by hand.
- Handle errors from the optimization pass so partial failures don't leave blocks unbound.
- Render optimized filters only via the SmartFilter runtime.
When it happens
Trigger: Calling getShaderBinding() on an OptimizedShaderBlock that was constructed manually or whose optimization pipeline never completed (e.g. SmartFilterOptimizer was not run, or threw before binding setup).
Common situations: Using optimized blocks outside the normal SmartFilter runtime flow; the optimizer run aborted midway due to another error, leaving blocks unbound; custom runtimes reading bindings before the first optimize pass.
Related errors
- Shader program not found for block "${block.name}"!
- Recast is not initialized. Please call InitRecast first.
- There is no NavMesh generated.
- Function not injected yet. Use the factory to create the plu
- There is no navMesh generated.
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/78548331182d6198.
Report an issue: GitHub.