Sub-workflows reduce duplication when they expose a stable, narrow contract. They should not become a hidden collection of unrelated actions or a way to share one credential across clients.
Find a Real Boundary
Good candidates:
- normalize and validate one event type;
- retrieve an approved catalog item;
- create a DRAFT CRM record idempotently;
- format an operator alert;
- apply a shared redaction policy.
Define input/output JSON, error codes, side effects, credentials, timeout, version, and owner. Treat the sub-workflow like an internal API.
{
"contract": "normalize-lead-v2",
"input": { "event_id": "...", "payload": {} },
"output": { "ok": true, "lead": {}, "warnings": [] }
}
Control Invocation
Use the current Execute Sub-workflow mechanisms and select which workflows may call it where supported. Keep tenant and authorization context server-derived. Do not accept a model-supplied tenant ID as authority.
Version breaking changes. Update callers deliberately, test old/new fixtures, and avoid recursive invocation. Set maximum execution time and make called side effects idempotent.
Maintain a call-graph inventory listing every caller, contract version, credential class, and expected volume. Before changing a shared workflow, run its fixtures against every supported caller. This catches a small output rename that would otherwise break several production canvases at once. Deprecate old versions with a dated migration and removal plan rather than editing them invisibly.
Worked Example
Three sales workflows need phone normalization and consent-state mapping. A shared normalize-contact-v2 receives an authorized contact reference and raw fields, returns canonical display/reference fields and warnings, and never sends a message.
It is tested with local/international formats, missing values, opt-out, and malformed input. Marketing eligibility remains in the authoritative consent service; normalization cannot turn consent on.
Failure Cases to Diagnose
- Sub-workflow takes arbitrary credentials: bind credentials to authorized instance/project.
- Output schema is undocumented: callers break silently.
- Everything becomes one mega-utility: split cohesive business capabilities.
- Recursive calls: enforce call graph and depth.
- Breaking edit changes all callers: version and migrate.
- Execution data leaks across clients: isolate projects/instances and tenant checks.
🇵🇰 Pakistan Angle
Reusable components are valuable for phone formatting, PKR display, city/service validation, and bilingual message templates, but they must not invent local rules. Store dated, business-approved configuration.
Agencies should deliver reusable code without centralizing every client credential in a personal instance. Client ownership and n8n licensing remain separate from technical reuse.
Hands-On Exercise
- Identify duplicated logic in two workflows.
- write the sub-workflow contract.
- implement versioned inputs/outputs/errors.
- test allowed caller, invalid caller/input, timeout, and replay.
- document migration and owner.
Completion Rubric
- Boundary is cohesive and reusable.
- Contract and errors are versioned.
- Caller/tenant/credential authority is controlled.
- Side effects are idempotent.
- Recursion and runtime are bounded.
- Migration and ownership are documented.
Sources
Key takeaway: make sub-workflows small internal APIs with contracts, authorization, versions, and bounded idempotent effects.