BabylonJS/Babylon.js · error
_releaseTexture: Trying to release a texture from a non exis
Error message
_releaseTexture: Trying to release a texture from a non existing pool ${textureOptionsHash}! What it means
The Smart Filter runtime maintains a pool of reusable render target textures keyed by a hash of their texture options. _releaseTexture decrements the ref count of a texture returned to the pool; this error is thrown when no pool entry exists for the given textureOptionsHash, meaning the runtime is asked to release a texture that was never created by (or has already been fully removed from) the render target pool. It guards only when _optimize is enabled, so it indicates internal bookkeeping corruption or a mismatched release call.
Source
Thrown at packages/dev/smartFilters/src/runtime/renderTargetGenerator.ts:160
refCountedTexture = {
texture: this._createTexture(runtime, smartFilter, textureOptions),
refCount: 0,
};
refCountedTextures.add(refCountedTexture);
this._numTargetsCreated++;
}
return refCountedTexture;
}
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
View on GitHub (pinned to 0592b347b8)
Solutions
- Check that _optimize stays consistent for the lifetime of the runtime; do not toggle optimization or re-create the generator mid-run.
- Ensure every texture is released exactly once — audit setOutputTextures/dispose paths for double-release calls.
- Verify textures being released were acquired from the same renderTargetGenerator instance that is releasing them.
- Re-create the runtime/renderTargetGenerator if it was disposed or its pool cleared; the pool state is unrecoverable.
- If reproducible, file an issue — this is normally an internal invariant violation, not user error.
Example fix
// before
runtime.setOutputTextures(oldTextures); // second release of already-released textures
// after
if (!runtime.isDisposed && !texturesReleased) {
runtime.setOutputTextures(oldTextures);
texturesReleased = true;
} Defensive patterns
Strategy: try-catch
Validate before calling
function canRelease(generator, hash, texture) {
const pool = generator._renderTargetPool;
return !!pool?.get(hash)?.some((rct) => rct.texture === texture);
} Type guard
function isInPool(generator, hash, texture) {
return (generator._renderTargetPool?.get(hash) ?? []).some((r) => r.texture === texture);
} Try / catch
try {
runtime.setOutputTextures(textures);
} catch (e) {
if (String(e.message).includes('_releaseTexture: Trying to release a texture from a non existing pool')) {
// pool bookkeeping corrupted: rebuild the runtime/generator
runtime.dispose();
runtime = rebuildRuntime();
} else { throw e; }
} Prevention
- Release each texture exactly once; track released textures in a Set.
- Keep _optimize setting constant for the generator's lifetime.
- Only pass textures obtained from the same generator instance back to it.
- Never release textures from a disposed or cleared runtime.
- Treat pool errors as internal bugs: log hash + texture identity for bug reports.
When it happens
Trigger: setOutputTextures (or other runtime teardown paths) calls _releaseTexture with a hash that has no entry in _renderTargetPool — e.g. releasing the same texture twice (double-release), releasing a texture created while _optimize was false, or an already-drained pool entry that was deleted after its ref count hit zero.
Common situations: Rendering the same Smart Filter runtime twice with differing optimization settings, re-using a runtime/disposed texture objects across runs, calling dispose or setOutputTextures twice on the same frame graph, or framework-level bugs where the pool was cleared between acquire and release.
Related errors
- _releaseTexture: Can't find the texture in the pool ${textur
- 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/082c79f3f6338ce0.
Report an issue: GitHub.