BabylonJS/Babylon.js · error
FrameGraphCopyToTextureTask "${this.name}": sourceTexture an
Error message
FrameGraphCopyToTextureTask "${this.name}": sourceTexture and targetTexture are required What it means
FrameGraphCopyToTextureTask.record() requires both a sourceTexture and a targetTexture handle because it creates a copy pass between two GPU textures. If either is undefined the pass has no valid source or destination, so the task throws immediately during record.
Source
Thrown at packages/dev/core/src/FrameGraph/Tasks/Texture/copyToTextureTask.ts:54
/**
* Constructs a new FrameGraphCopyToTextureTask.
* @param name The name of the task.
* @param frameGraph The frame graph the task belongs to.
*/
constructor(name: string, frameGraph: FrameGraph) {
super(name, frameGraph);
this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();
}
public override getClassName(): string {
return "FrameGraphCopyToTextureTask";
}
public record() {
if (this.sourceTexture === undefined || this.targetTexture === undefined) {
throw new Error(`FrameGraphCopyToTextureTask "${this.name}": sourceTexture and targetTexture are required`);
}
this._frameGraph.textureManager.resolveDanglingHandle(this.outputTexture, this.targetTexture);
const pass = this._frameGraph.addRenderPass(this.name);
const passDisabled = this._frameGraph.addRenderPass(this.name + "_disabled", true);
pass.addDependencies(this.sourceTexture);
passDisabled.addDependencies(this.sourceTexture);
const textureDescription = this._frameGraph.textureManager.getTextureDescription(this.targetTexture);
const targetIsDepthTexture = IsDepthTexture(textureDescription.options.formats![0]);
if (targetIsDepthTexture) {
pass.setRenderTargetDepth(this.outputTexture);
passDisabled.setRenderTargetDepth(this.outputTexture);
} else {
pass.setRenderTarget(this.outputTexture);
View on GitHub (pinned to 0592b347b8)
Solutions
- Set both task.sourceTexture and task.targetTexture to valid frame graph texture handles before build().
- Verify the producing tasks are added to the graph and their outputTextures are assigned to this task's inputs.
- Remove the task entirely if the copy is no longer needed.
Example fix
// before
copyTask.sourceTexture = blurTask.outputTexture;
fg.addTask(copyTask);
// after
copyTask.sourceTexture = blurTask.outputTexture;
copyTask.targetTexture = fg.createTexture({ name: 'copyTarget', options: { ... } });
fg.addTask(copyTask); Defensive patterns
Strategy: validation
Validate before calling
if (copyTask.sourceTexture === undefined || copyTask.targetTexture === undefined) {
throw new Error('copyTask needs both sourceTexture and targetTexture before build()');
} Type guard
function isCopyReady(t: { sourceTexture?: unknown; targetTexture?: unknown }): boolean {
return t.sourceTexture !== undefined && t.targetTexture !== undefined;
} Prevention
- Assign both endpoints of a copy at the same call site to avoid half-wired tasks.
- Keep a checklist of task inputs when building pipeline graphs.
When it happens
Trigger: Adding FrameGraphCopyToTextureTask to a frame graph and calling build() with only sourceTexture set, only targetTexture set, or neither.
Common situations: Copy pipelines (e.g. for post-processing or readback) where one endpoint of the copy was not wired; a texture-producing task removed or renamed leaving a dangling undefined handle; conditional pipelines that skip creating the target texture.
Related errors
- FrameGraphCopyToBackbufferColorTask "${this.name}": sourceTe
- FrameGraphClearTextureTask ${this.name}: the depth texture (
- FrameGraphGenerateMipMapsTask ${this.name}: targetTexture is
- FrameGraphRenderTarget.renderTargetWrapper: Failed to get te
- Unable to create webGL texture
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/3e3b73e839703aa2.
Report an issue: GitHub.