{"record":{"id":"39bbd7482153043f","repo":"BabylonJS/Babylon.js","slug":"framegraph-addtask-can-t-add-the-task-task-nam","errorCode":null,"errorMessage":"FrameGraph.addTask: Can't add the task \"${task.name}\" while another task is currently building (task: ${this._currentProcessedTask.name}).","messagePattern":"FrameGraph\\.addTask: Can't add the task \"(.+?)\" while another task is currently building \\(task: (.+?)\\)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/core/src/FrameGraph/frameGraph.ts","lineNumber":182,"sourceCode":"\r\n    /**\r\n     * Gets all tasks of a specific type, based on their class name\r\n     * @param taskClassName Class name(s) of the task(s) to get\r\n     * @returns The list of tasks of the specified type\r\n     */\r\n    public getTasksByClassName<T extends FrameGraphTask>(taskClassName: string | string[]): T[] {\r\n        return Array.isArray(taskClassName)\r\n            ? (this._tasks.filter((t) => taskClassName.includes(t.getClassName())) as T[])\r\n            : (this._tasks.filter((t) => t.getClassName() === taskClassName) as T[]);\r\n    }\r\n\r\n    /**\r\n     * Adds a task to the frame graph\r\n     * @param task Task to add\r\n     */\r\n    public addTask(task: FrameGraphTask): void {\r\n        if (this._currentProcessedTask !== null) {\r\n            throw new Error(`FrameGraph.addTask: Can't add the task \"${task.name}\" while another task is currently building (task: ${this._currentProcessedTask.name}).`);\r\n        }\r\n\r\n        if (this._tasks.includes(task)) {\r\n            return;\r\n        }\r\n\r\n        this._tasks.push(task);\r\n        this._initAsyncPromises.push(task.initAsync());\r\n    }\r\n\r\n    /**\r\n     * Adds a pass to a task. This method can only be called during a Task.record execution.\r\n     * @param name The name of the pass\r\n     * @param whenTaskDisabled If true, the pass will be added to the list of passes to execute when the task is disabled (default is false)\r\n     * @returns The render pass created\r\n     */\r\n    public addPass(name: string, whenTaskDisabled = false): FrameGraphPass<FrameGraphContext> {\r\n        return this._addPass(name, FrameGraphPassType.Normal, whenTaskDisabled) as FrameGraphPass<FrameGraphContext>;\r","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/core/src/FrameGraph/frameGraph.ts#L164-L200","documentation":"FrameGraph.addTask() refuses to add a new task while another task is inside its build/record phase (this._currentProcessedTask !== null). Frame graph tasks call addTask/record recursively or from callbacks; nesting task addition during another task's recording would corrupt graph construction, so it throws.","triggerScenarios":"Calling frameGraph.addTask() from inside a task's record() execution (e.g. a custom task that tries to add other tasks during recording), or from a callback invoked while build() is processing a task — e.g. CreateScreenshotForFrameGraphAsync triggering recording.","commonSituations":"Custom FrameGraphTask implementations that add child tasks inside record(); asynchronous code (screenshots, asset loading callbacks) resolving during an active build(); re-entrant build() calls from event handlers.","solutions":["Move addTask calls outside of record()/build() — add all tasks up front, then call build() once.","Inside a custom task's record(), use frameGraph.addRenderPass/addObjectListPass to create passes instead of adding tasks.","Defer the addTask with a queue that is flushed after build() completes (e.g. in a build().then(...) continuation)."],"exampleFix":"// before\npublic record() {\n  this._frameGraph.addTask(new FrameGraphClearTextureTask('clear'));\n}\n// after\npublic record() {\n  const pass = this._frameGraph.addRenderPass(this.name);\n  pass.setExecuteFunc((ctx) => { /* clear work */ });\n}","handlingStrategy":"try-catch","validationCode":"if (frameGraph['_currentProcessedTask']) {\n  throw new Error('Cannot addTask while frame graph is building');\n}","typeGuard":null,"tryCatchPattern":"try {\n  frameGraph.addTask(task);\n} catch (e) {\n  if (String(e.message).includes('while another task is currently building')) {\n    pendingTasks.push(task); // flush after build() resolves\n  } else {\n    throw e;\n  }\n}","preventionTips":["Never call addTask from inside record() or async callbacks racing with build().","Queue deferred tasks and add them after build() completes."],"tags":["babylonjs","framegraph","reentrancy","task-lifecycle"],"backgroundTag":"reentrant-call-forbidden","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}