Flow Studio
Nodes With No Output
What happens when a node returns NodeExecutionResult.Skip() or null — how the engine handles empty outputs and what downstream nodes observe.
When to Return Skip
NodeExecutionResult.Skip() signals that the node completed without producing meaningful data and does not wish to route to any downstream node. Common use cases:
- A conditional guard node that checks a condition and decides to halt this branch silently
- A logging/audit node that has a side-effect but no data to pass forward
- A node that detects it has already run and skips duplicate execution
public class IdempotencyCheckExecutor : BaseNodeExecutor
{
public override async Task<NodeExecutionResult> ExecuteAsync(NodeExecutionContext ctx)
{
var key = ctx.GetInput<string>("idempotencyKey");
if (await _cache.ExistsAsync(key))
{
// Already processed — skip silently, do not continue
return NodeExecutionResult.Skip();
}
await _cache.SetAsync(key);
return NodeExecutionResult.Success(new { processed = true });
}
}
What Skip Does to the Graph
When Skip() is returned:
ExecutionMemory.nodeOutputs[nodeId]is set tonull- No edges from any port are followed — execution stops at this node for this branch
- If the node is part of a join, the join gateway treats this branch as completed with null
- The node status in the observer panel shows as "Skipped" (gray icon)
Null Output vs. Skip
| Return Value | Memory Entry | Routing | Observer State |
|---|---|---|---|
Skip() | null | No edges followed | Skipped |
Success(null) | null | Main port edges followed | Completed |
Success(new {}) | {} | Main port edges followed | Completed |
Key distinction:
Success(null) still routes downstream via the main port — it just passes null as the data. Skip() halts routing entirely. Use Skip() only when you intentionally want to stop this execution branch.
Accessing Null Output Safely
If a downstream node references a skipped node's output, it receives null. Guard with optional chaining:
// idempotencyCheck was skipped — its output is null
$output.idempotencyCheck?.processed ?? false // → false (safe)
$output.idempotencyCheck.processed // → runtime error: cannot read property of null
Fire-and-Forget Side-Effect Nodes
Nodes that perform side effects (send a log event, increment a counter, post to an analytics service) but have no downstream consumers should return Success(new { ok = true }) rather than Skip(). This records that the node ran and provides a completion signal for join gateways:
// Audit logger — fire-and-forget style
return NodeExecutionResult.Success(new
{
ok = true,
auditId = auditEntry.Id,
timestamp = DateTimeOffset.UtcNow
});