BabylonJS/Babylon.js · error · Error

You must define the outputBlock property before building the

Error message

You must define the outputBlock property before building the node render graph

What it means

NodeRenderGraph.buildAsync requires an output block: it is the sink that finalizes the frame graph. Building without one would produce a graph with no visible output, so the method throws immediately.

Source

Thrown at packages/dev/core/src/FrameGraph/Node/nodeRenderGraph.ts:354

    private _createNodeEditor(additionalConfig?: any) {
        const nodeEditorConfig: any = {
            nodeRenderGraph: this,
            customBlockDescriptions: NodeRenderGraph.CustomBlockDescriptions,
            ...additionalConfig,
        };
        this.BJSNODERENDERGRAPHEDITOR.NodeRenderGraphEditor.Show(nodeEditorConfig);
    }

    /**
     * Build the final list of blocks that will be executed by the "execute" method.
     * It also builds the underlying frame graph unless specified otherwise.
     * @param dontBuildFrameGraph If the underlying frame graph should not be built (default: false)
     * @param waitForReadiness If the method should wait for the frame graph to be ready before resolving (default: true). Note that this parameter has no effect if "dontBuildFrameGraph" is true.
     * @param setAsSceneFrameGraph If the built frame graph must be set as the scene's frame graph (default: true)
     */
    public async buildAsync(dontBuildFrameGraph = false, waitForReadiness = true, setAsSceneFrameGraph = true): Promise<void> {
        if (!this.outputBlock) {
            throw new Error("You must define the outputBlock property before building the node render graph");
        }

        if (setAsSceneFrameGraph) {
            this._scene.frameGraph = this._frameGraph;
        }

        this._initializeBlock(this.outputBlock);

        this._frameGraph.clear();

        const state = new NodeRenderGraphBuildState();

        state.buildId = this._buildId;
        state.verbose = this._options.verbose!;

        if (this._options.autoFillExternalInputs) {
            this._autoFillExternalInputs();
        }

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Create an output block and assign it: nodeRenderGraph.outputBlock = outputBlock before building
  2. Wire your graph's final color into the output block's input
  3. Re-add the output block if it was removed during editing/loading

Example fix

// before
const graph = new NodeRenderGraph(...);
graph.buildAsync();
// after
const output = new NodeRenderGraphOutputBlock("output");
graph.outputBlock = output;
colorBlock.output.connectTo(output.input);
graph.buildAsync();
Defensive patterns

Strategy: validation

Validate before calling

if (!nodeRenderGraph.outputBlock) {
  throw new Error('attach an output block before buildAsync()');
}

Type guard

function hasOutputBlock(g) { return g.outputBlock != null; }

Try / catch

try { await nodeRenderGraph.buildAsync(); } catch (e) { if (e.message.includes('You must define the outputBlock')) { console.error('Add a NodeRenderGraphOutputBlock and wire final color to it'); } else { throw e; } }

Prevention

When it happens

Trigger: Calling buildAsync() (directly or via constructor, CreateDefaultAsync, replaceCameraAsync, or context-menu default-graph creation) when the outputBlock property is null/undefined.

Common situations: Manually assembling a node render graph and forgetting to add an output block; clearing the output block before rebuilding; JSON loading that omitted the output node.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/15e8c4aec2c1e99d. Report an issue: GitHub.