NodeId Naming
How the canvas assigns and manages node IDs, why naming matters for expressions, and best practices for renaming nodes in production workflows.
What Is the NodeId?
Every node on the canvas has a unique nodeId — this is the key used in $output.{nodeId} expressions. The ID is also stored in ExecutionMemory.nodeOutputs as the dictionary key.
The nodeId is distinct from the node's display label. The label is a human-readable name shown on the canvas tile; the ID is the programmatic key used in all expression references.
Auto-Generated IDs
When you drag a node onto the canvas, the designer auto-generates a unique ID using a UUID-based scheme:
// Simplified from WorkflowStore
function addNode(nodeType: string): WorkflowNode {
return {
id: `${nodeType}-${nanoid(8)}`, // e.g., "httpRequest-aB3kX9qR"
type: nodeType,
label: nodeType,
// ...
};
}
The default ID is not human-friendly. Renaming nodes early in design is strongly recommended.
Renaming a Node
In the Node Inspector panel (right sidebar), set the Node ID field to a meaningful camelCase or snake_case identifier. The designer enforces:
- Unique within the workflow
- Alphanumeric + underscore + hyphen only
- No spaces (use
fetchCustomernotfetch customer) - Not a reserved keyword (
main,error,timeout)
Impact of Renaming on Expressions
// Designer rename validation
function renameNode(oldId: string, newId: string): ValidationResult {
const references = findExpressionReferences(oldId);
if (references.length > 0) {
return {
valid: false,
warning: `${references.length} expressions reference $output.${oldId}. Update them after rename.`,
affectedNodes: references.map(r => r.nodeId)
};
}
return { valid: true };
}
Naming Conventions
| Pattern | Example | When to Use |
|---|---|---|
| camelCase verb+noun | fetchEmployee | Action nodes — HTTP calls, service calls |
| camelCase noun+verb | invoiceCreated | Event/trigger nodes |
| camelCase descriptive | creditCheckResult | Decision/evaluation nodes |
| snake_case with step prefix | step1_validateInput | Sequential linear workflows |
NodeId in Execution Memory
After execution, the node ID is the key in the persisted execution memory. If you look at a historical execution in the observer panel, you'll see the nodeId as the key for each output entry. This is why stable, meaningful IDs matter for debugging:
{
"nodeOutputs": {
"fetchEmployee": { "employeeId": "emp-001", "name": "Alice" },
"creditCheck": { "score": 740, "tier": "standard" },
"sendApprovalEmail": { "messageId": "msg-xyz" }
}
}