{"record":{"id":"0b53db8be154673f","repo":"mrdoob/three.js","slug":"three-webglrenderer-readrendertargetpixels-render","errorCode":null,"errorMessage":"THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.","messagePattern":"THREE\\.WebGLRenderer\\.readRenderTargetPixels: renderTarget is not THREE\\.WebGLRenderTarget\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/renderers/WebGLRenderer.js","lineNumber":3186,"sourceCode":"\t\t *\n\t\t * It is recommended to use this version of `readRenderTargetPixels()` whenever possible.\n\t\t *\n\t\t * @async\n\t\t * @param {WebGLRenderTarget} renderTarget - The render target to read from.\n\t\t * @param {number} x - The `x` coordinate of the copy region's origin.\n\t\t * @param {number} y - The `y` coordinate of the copy region's origin.\n\t\t * @param {number} width - The width of the copy region.\n\t\t * @param {number} height - The height of the copy region.\n\t\t * @param {TypedArray} buffer - The result buffer.\n\t\t * @param {number} [activeCubeFaceIndex] - The active cube face index.\n\t\t * @param {number} [textureIndex=0] - The texture index of an MRT render target.\n\t\t * @return {Promise<TypedArray>} A Promise that resolves when the read has been finished. The resolve provides the read data as a typed array.\n\t\t */\n\t\tthis.readRenderTargetPixelsAsync = async function ( renderTarget, x, y, width, height, buffer, activeCubeFaceIndex, textureIndex = 0 ) {\n\n\t\t\tif ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {\n\n\t\t\t\tthrow new Error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );\n\n\t\t\t}\n\n\t\t\tlet framebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\t\t\tif ( renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined ) {\n\n\t\t\t\tframebuffer = framebuffer[ activeCubeFaceIndex ];\n\n\t\t\t}\n\n\t\t\tif ( framebuffer ) {\n\n\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t// set the active frame buffer to the one we want to read\n\t\t\t\t\tstate.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n","sourceCodeStart":3168,"sourceCodeEnd":3204,"githubUrl":"https://github.com/mrdoob/three.js/blob/da05705fa31f02710c19772a2aa70c7454807f0c/src/renderers/WebGLRenderer.js#L3168-L3204","documentation":"Thrown by readRenderTargetPixelsAsync when the passed renderTarget is null/undefined or lacks the isWebGLRenderTarget flag. The async variant throws (unlike the sync readRenderTargetPixels which only warns) because async pipelines expect hard failures.","triggerScenarios":"Passing a regular Texture, a canvas, null, a WebGLCubeRenderTarget used incorrectly, or any object that is not a WebGLRenderTarget to readRenderTargetPixelsAsync.","commonSituations":"Refactoring from readRenderTargetPixels (sync) to the async variant and passing the same unguarded arguments; passing a texture instead of its owning render target; passing the result of a function that may return null.","solutions":["Ensure the argument is a WebGLRenderTarget (or WebGLCubeRenderTarget, which extends it) before calling.","Guard: if (renderTarget && renderTarget.isWebGLRenderTarget) { ... } around the call.","For cube render targets, pass the correct activeCubeFaceIndex and confirm isWebGLCubeRenderTarget if needed.","Check that the render target was created with new THREE.WebGLRenderTarget(...) and not disposed."],"exampleFix":"// before\nconst data = await renderer.readRenderTargetPixelsAsync( someTexture, 0, 0, w, h, buf ); // not a RT\n\n// after\nif ( renderTarget && renderTarget.isWebGLRenderTarget ) {\n  const data = await renderer.readRenderTargetPixelsAsync( renderTarget, 0, 0, w, h, buf );\n}","handlingStrategy":"type-guard","validationCode":"if ( renderTarget && renderTarget.isWebGLRenderTarget ) {\n  const data = await renderer.readRenderTargetPixelsAsync( renderTarget, 0, 0, w, h, buf );\n}","typeGuard":"function isWebGLRenderTarget( obj ) {\n  return obj != null && obj.isWebGLRenderTarget === true;\n}","tryCatchPattern":null,"preventionTips":["Always check renderTarget.isWebGLRenderTarget before the async read.","Pass a WebGLRenderTarget (or WebGLCubeRenderTarget) instance only.","Handle null/undefined returns from upstream functions before reading.","Remember the async variant throws where the sync one only warns."],"tags":["webglrenderer","rendertarget","readback","type-guard"],"backgroundTag":null,"analyzedSha":"da05705fa31f02710c19772a2aa70c7454807f0c","analyzedAt":"2026-08-12T22:51:37.160Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}