Budibase/budibase · error
Cannot render an empty flow chain
Error message
Cannot render an empty flow chain
What it means
The FlowChart's render pipeline (getRenderResult, invoked by renderChain) computes layout for a chain of automation flow nodes and needs at least one node's source to anchor the rendering. When getLastSource returns undefined — meaning the chain context has no nodes — rendering cannot proceed and this error is thrown.
Source
Thrown at packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowCanvas/renderers/FlowChainRenderer.ts:105
const renderBlock = (step: AutomationBlock, context: ChainRenderContext) => {
if (step.stepId === AutomationActionStepId.BRANCH) {
renderBranchSplit(step, context)
return false
}
if (isLoopV2Step(step)) {
renderLoop(step, context)
return true
}
renderStep(step, context)
return true
}
const getRenderResult = (context: ChainRenderContext): ChainRenderResult => {
const lastSource = getLastSource(context)
if (!lastSource) {
throw new Error("Cannot render an empty flow chain")
}
return {
lastNodeId: lastSource.nodeId,
lastNodeBlock: lastSource.block,
bottomY: context.currentY,
branched: context.branched,
terminals: context.terminals,
}
}
export const renderChain = (
chain: AutomationBlock[],
parentNodeId: string,
parentBlock: FlowBlockContext,
startY: number,
deps: GraphBuildDeps
): ChainRenderResult => {View on GitHub (pinned to a81a902e9a)
Solutions
- Ensure the automation chain being rendered contains at least one node before calling renderChain.
- Add a guard in the caller: skip rendering (or render an empty-state placeholder) when the node list is empty.
- If nodes are filtered out upstream, keep the trigger/root node in the context so the chain is never empty.
Example fix
// before renderChain(context) // context.nodes may be [] // after if (context.nodes.length === 0) return renderEmptyState() renderChain(context)
Defensive patterns
Strategy: validation
Validate before calling
const canRenderChain = (ctx: ChainRenderContext): boolean =>
getLastSource(ctx) != null // or: ctx.nodes.length > 0
if (!canRenderChain(context)) {
return renderEmptyStatePlaceholder()
}
const result = renderChain(context) Type guard
const hasChainSource = (ctx: ChainRenderContext): ctx is ChainRenderContext & { nodes: [Node, ...Node[]] } =>
ctx.nodes.length > 0 Try / catch
let result: ChainRenderResult
try {
result = renderChain(context)
} catch (err) {
if (err instanceof Error && err.message === "Cannot render an empty flow chain") {
result = emptyChainRenderResult()
} else throw err
} Prevention
- Always keep the trigger/root node in the render context.
- Render an explicit empty-state UI when an automation has no steps.
- Filter nodes before building the context, not inside the renderer contract.
When it happens
Trigger: renderChain called with a ChainRenderContext whose node list is empty — e.g. an automation with zero steps, a branch that filtered out all nodes, or a context constructed without seeding an initial node/block.
Common situations: Builder UI rendering an automation where the user deleted every step; a test or extension constructing a chain context manually and forgetting the first node; upstream filtering (enabled=false, block missing) removing all nodes before render.
Related errors
- Unexpected response ${response.statusText}
- No response received for attachment
- Unexpected response body stream type
- Invalid signed URL
- Source table '${relationship.sourceTable}' not found in data
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/d89485c21ae2815c.
Report an issue: GitHub.