Sub-workflows and Template Reuse
Chapter 19: Sub-workflows and Template Reuse
As your n8n workflow library grows, duplication becomes a real problem โ the same Feishu notification logic scattered across dozens of workflows, each requiring individual updates when the message format changes. Sub-workflows solve this: encapsulate shared logic once, call it from anywhere via the Execute Workflow node, and update it in a single place. This chapter covers parameter passing, return values, shared module patterns, and team collaboration settings.
19.1 The Execute Workflow Node
The Execute Workflow node lets one workflow synchronously call another, wait for it to finish, and receive its output. The called workflow uses an Execute Workflow Trigger node as its entry point (not a Webhook or Schedule).
How it works:
- The parent workflow pauses at the Execute Workflow node and triggers the specified sub-workflow
- The sub-workflow runs from its Execute Workflow Trigger node
- The sub-workflow's last node output is returned to the parent
- The parent continues execution
Sync vs Async: In sync mode (default), the parent waits for the child to complete. In async mode, the parent triggers the child and immediately moves on โ useful for fire-and-forget notifications where the return value is not needed.
19.2 Passing Parameters: Parent โ Child
// Execute Workflow node config
{
"name": "Run: Feishu Notify",
"type": "n8n-nodes-base.executeWorkflow",
"parameters": {
"workflowId": "={{ $vars.FEISHU_NOTIFY_WORKFLOW_ID }}",
"mode": "sync",
"workflowInputs": {
"values": [
{ "name": "title", "value": "={{ $json.title }}" },
{ "name": "message", "value": "={{ $json.errorMessage }}" },
{ "name": "level", "value": "error" }
]
}
}
}
Store workflow IDs in n8n Variables (global variables) so that if a sub-workflow is recreated with a new ID, you only update the variable, not every parent workflow.
19.3 Return Values: Child โ Parent
The output of a sub-workflow's last node is returned to the parent. End every sub-workflow with a Set node that explicitly defines the return fields. The parent accesses them via $('Run: Feishu Notify').item.json.success.
// Sub-workflow's final Set node โ defines return values
{
"name": "Return Result",
"type": "n8n-nodes-base.set",
"parameters": {
"assignments": {
"assignments": [
{ "name": "success", "value": true, "type": "boolean" },
{ "name": "sentAt", "value": "={{ $now.toISO() }}", "type": "string" }
]
}
}
}
19.4 Shared Module Patterns
Two sub-workflows every production n8n deployment should have:
Notification Module
Accepts parameters: title, message, level (info/warn/error), chatId. Selects message color and icon based on level; sends a rich Feishu card. When the Feishu API changes, update this one sub-workflow and every business workflow gets the fix automatically.
Error Handler
Configure it as the "Error Workflow" for all production workflows (in Workflow Settings). It automatically captures the failing workflow name, node name, and error message, sends an alert to the ops channel, and logs the error to a workflow_errors database table.
Best practice: Set the same error handler sub-workflow as the "Error Workflow" in every production workflow's settings. One place to maintain error handling logic, one consistent log format, one alert channel.
19.5 Workflow Templates
Export workflows as JSON (Editor menu โ Download). The export includes all node configs but excludes credential values (by design). Import by dragging the JSON into the n8n canvas or using the Import menu.
For team reuse, maintain a Git repository of workflow JSON files organized by business domain:
n8n-templates/
โโโ common/
โ โโโ feishu-notify.json
โ โโโ error-handler.json
โ โโโ send-email.json
โโโ marketing/
โ โโโ content-pipeline.json
โโโ devops/
โ โโโ deploy-notify.json
โโโ README.md
Bulk export with n8n CLI
# Export all workflows from the n8n container
docker exec -it n8n-n8n-1 \
n8n export:workflow \
--all \
--output=/home/node/.n8n/exports/
# Copy out and commit to Git
docker cp n8n-n8n-1:/home/node/.n8n/exports/ ./workflow-backups/$(date +%Y%m%d)/
cd ./workflow-backups
git add . && git commit -m "chore: workflow backup $(date +%Y-%m-%d)"
19.6 Version Management and Rollback
For self-hosted users (enterprise has built-in version history):
- Manual export + Git: export JSON before modifying any important workflow; restore old JSON to roll back
- Naming conventions: add version numbers to workflow names (e.g. "Content Pipeline v2.3"); deactivate old versions instead of deleting them
- Scheduled CLI exports: integrate into CI/CD for regular automated backups
19.7 Team Collaboration and Permissions
Share workflows via the Share button (top-right menu). Assign roles per team member:
| Role | Capabilities | Use case |
|---|---|---|
| Owner | Full control, can delete | Workflow creator |
| Editor | View and edit, cannot delete | Team collaborative development |
| Viewer | Read-only | Audit, knowledge sharing |
For shared sub-workflows like the notification module, grant all team members Editor access and agree on a change notification process (announce in the team channel before modifying shared modules).
Credentials sharing note: Credentials have a separate sharing mechanism. Team API keys (like the Feishu bot token) should be created by an admin and shared with team members. Members can use the credential but cannot view the raw key value.