pixijs/pixijs · error · Error
[RenderTarget] cannot attach a depth-stencil texture to the
Error message
[RenderTarget] cannot attach a depth-stencil texture to the screen — the canvas owns its own depth/stencil buffers. Render to a texture target instead.
What it means
Thrown by RenderTarget when a depth-stencil texture is attached to a root (screen) target. The screen/canvas owns its own depth and stencil buffers provided by the context (WebGL default framebuffer or the WebGPU canvas configuration), so an external depth-stencil texture cannot be bound there.
Source
Thrown at src/rendering/renderers/shared/renderTarget/RenderTarget.ts:277
colorAttachments.push({
texture: texture.source,
loadOp: 'clear',
storeOp: 'store',
});
});
}
const wantsDepthStencilTexture = opts.depthStencilTexture === true;
this._depth = !!(opts.depth || wantsDepthStencilTexture);
this._stencil = !!(opts.stencil || wantsDepthStencilTexture);
if (opts.depthStencilTexture instanceof Texture
|| opts.depthStencilTexture instanceof TextureSource)
{
if (opts.isRoot)
{
throw new Error('[RenderTarget] cannot attach a depth-stencil texture to the screen — '
+ 'the canvas owns its own depth/stencil buffers. Render to a texture target instead.');
}
depthStencilAttachment = {
texture: opts.depthStencilTexture.source,
};
}
else if ((wantsDepthStencilTexture && !opts.isRoot)
|| ((opts.stencil || opts.depth) && colorAttachments.length === 0))
{
// an explicit texture request (depthStencilTexture: true) or a depth-only target.
// Plain depth/stencil flags create no texture — each backend picks the cheapest
// resource (renderbuffer on WebGL, internal texture on WebGPU, context buffers
// for the screen)
depthStencilAttachment = this._createDepthStencilTexture(opts.width, opts.height, opts.resolution);
}
return {View on GitHub (pinned to 4b141e3ced)
Solutions
- Drop `depthStencilTexture` from the root target — let the canvas manage its own depth/stencil via `depth`/`stencil` flags or renderer configuration.
- Render into an offscreen texture target (isRoot: false) if you must share a specific depth-stencil texture.
- Separate your 'screen pass' configuration object from your 'offscreen pass' configuration so root-specific options never leak.
Example fix
// before
new RenderTarget({ isRoot: true, depthStencilTexture: sharedDepthTex });
// after
new RenderTarget({ isRoot: true, depth: true, stencil: true }); Defensive patterns
Strategy: validation
Validate before calling
function assertRootOpts(opts) {
if (opts.isRoot && (opts.depthStencilTexture instanceof Texture || opts.depthStencilTexture instanceof TextureSource)) {
throw new Error('Root cannot take depthStencilTexture');
}
} Type guard
function isRootSafeOpts(opts): boolean {
return !opts.isRoot || !(opts.depthStencilTexture instanceof Texture || opts.depthStencilTexture instanceof TextureSource);
} Prevention
- Keep root-target configs separate from offscreen configs.
- Never pass a shared depth-stencil texture to an isRoot target.
When it happens
Trigger: Constructing a RenderTarget with `isRoot: true` together with `depthStencilTexture: <Texture|TextureSource>` (or passing such a Texture through the root render-surface options).
Common situations: Reusing a depth-stencil texture across both screen and offscreen passes; copying an offscreen RenderTarget config verbatim into the root target; misconfiguring the application's main render surface.
Related errors
- [RenderTarget] no color textures or depth textures were prov
- [RenderTargetSystem] Rendering to mip levels is not supporte
- [RenderTargetSystem] Rendering to array layers is not suppor
- [Resolver] GenerateBundleAssetId are not working correctly
- [Resolver] alias is undefined for this asset: ${formattedAss
AI-assisted analysis of pixijs/pixijs@4b141e3ced (2026-08-12).
Data as JSON: /api/errors/b1f9f0c16cf0297f.
Report an issue: GitHub.