BabylonJS/Babylon.js · error
_releaseTexture: Can't find the texture in the pool ${textur
Error message
_releaseTexture: Can't find the texture in the pool ${textureOptionsHash}! What it means
When releasing a render target texture, the pool entry for the textureOptionsHash exists, but none of the ref-counted textures inside it matches the texture being released. The runtime tracks textures by identity within each pool bucket, so this means the texture object was never pooled under that hash (wrong hash, a different texture instance, or the matching entry was already evicted). Like error 860 it only fires when _optimize is on.
Source
Thrown at packages/dev/smartFilters/src/runtime/renderTargetGenerator.ts:170
private _releaseTexture(texture: ThinTexture, textureOptionsHash: string) {
if (!this._optimize) {
return;
}
const refCountedTextures = this._renderTargetPool.get(textureOptionsHash);
if (!refCountedTextures) {
throw new Error(`_releaseTexture: Trying to release a texture from a non existing pool ${textureOptionsHash}!`);
}
for (const refCountedTexture of refCountedTextures) {
if (refCountedTexture.texture === texture) {
refCountedTexture.refCount--;
return;
}
}
throw new Error(`_releaseTexture: Can't find the texture in the pool ${textureOptionsHash}!`);
}
/**
* Creates an offscreen texture to hold on the result of the block rendering.
* @param runtime - The current runtime we create the texture for
* @param smartFilter - The smart filter the texture is created for
* @param textureOptions - The options to use to create the texture
* @returns The render target texture
*/
private _createTexture(runtime: InternalSmartFilterRuntime, smartFilter: SmartFilter, textureOptions: OutputTextureOptions): ThinRenderTargetTexture {
const engine = runtime.engine;
// We are only rendering full screen post process without depth or stencil information
const setup: RenderTargetCreationOptions = {
generateDepthBuffer: false,
generateStencilBuffer: false,
generateMipMaps: false,
samplingMode: 2, // Babylon Constants.TEXTURE_LINEAR_LINEAR,
View on GitHub (pinned to 0592b347b8)
Solutions
- Release the exact texture object returned by the generator — never a copy, clone, or re-created texture with the same options.
- Verify the textureOptionsHash derivation matches how the texture was originally acquired.
- Check for double-release: once a texture is returned to the pool, drop the reference instead of releasing again.
- Keep all acquire/release pairs within a single runtime/generator instance lifetime.
- If it persists, capture the hash and texture id and report — indicates an internal ref-counting bug.
Example fix
// before const tex = generator.createRenderTargetTexture(options); tex.dispose(); // released externally, generator release later fails // after const tex = generator.createRenderTargetTexture(options); // let the runtime release it: runtime._releaseTexture(hash, tex) exactly once
Defensive patterns
Strategy: try-catch
Validate before calling
function canRelease(generator, hash, texture) {
return (generator._renderTargetPool?.get(hash) ?? []).some((r) => r.texture === texture);
} Type guard
function textureMatchesPoolEntry(texture, entry) {
return entry != null && entry.texture === texture;
} Try / catch
try {
generator._releaseTexture(hash, texture);
} catch (e) {
if (String(e.message).startsWith("_releaseTexture: Can't find the texture in the pool")) {
console.warn("Skipping release of non-pooled texture", hash);
} else { throw e; }
} Prevention
- Always release the identical object reference returned by acquire — no clones.
- Verify hash derivation matches the acquire-time options.
- Guard against double release with a released-flags set.
- Confine acquire/release to one runtime lifetime.
- Compare textures by identity, never structural equality.
When it happens
Trigger: _releaseTexture iterates refCountedTextures for the hash and finds no entry whose .texture === the passed texture — caused by passing a texture created with different options (different hash bucket), passing a stale/cloned texture reference, or releasing a texture twice after the first release removed/mutated bookkeeping.
Common situations: Caching Babylon.js texture objects across runtime rebuilds, comparing textures by structural equality instead of identity, mixing textures produced by two generators, or framework bugs in the frame-graph release path.
Related errors
- _releaseTexture: Trying to release a texture from a non exis
- Initial color gradient values not found in context.
- SmartAssetManager: Unknown manager state.
- Aggregate blocks should not be prepared for runtime.
- Cannot register an input connection point with no internal c
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/325e76aeb3789ec6.
Report an issue: GitHub.