n8n-connections
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesen8n Connections
n8n 连接
n8n's SDK has a small connection grammar. Two of its shapes silently produce broken workflows that pass validation. This skill is mostly about not falling into those traps.
n8n的SDK包含一套简洁的连接语法。其中两种写法会生成能通过验证但实际运行异常的工作流。本技能主要讲解如何避开这些陷阱。
The non-negotiable: the .to()
trap
.to()不可妥协的规则:.to()
陷阱
.to().to().add()ts
.add(node.output(0)).to(target) // ❌ connection silently dropped
.add(node.output(0).to(target)) // ✅validate_workflowIf you've written outside the parens, you have a bug. No exceptions.
<!-- TEMPORARY: .to()-after-.add() silent drop -->.add(...).to(...).to().add()ts
.add(node.output(0)).to(target) // ❌ 连接被静默丢弃
.add(node.output(0).to(target)) // ✅ 正确写法validate_workflow如果你写了(在括号外),那肯定存在bug,没有例外。
<!-- TEMPORARY: .to()-after-.add() silent drop -->.add(...).to(...).to()The universal connection pattern
通用连接模式
One shape covers IF/Switch branches, error outputs, merge inputs, and any generic multi-IO:
ts
.add(source.output(n).to(target))- : pick the output (0-indexed)
source.output(n) - : pick the target (default input 0)
.to(target) - : pick a specific input on the target (0-indexed)
.to(target.input(m))
Call once per wire. To fan out, repeat .
.add().add()有一种写法适用于IF/Switch分支、错误输出、Merge输入以及任何通用多IO场景:
ts
.add(source.output(n).to(target))- :选择输出(从0开始索引)
source.output(n) - :选择目标节点(默认使用输入0)
.to(target) - :选择目标节点上的特定输入(从0开始索引)
.to(target.input(m))
每个连接调用一次。要实现扇出,重复调用即可。
.add().add()Decision tree
决策树
Wiring a connection?
├── Linear (one source → one target, single output, single input)?
│ └── .add(source).to(target). The simple case; .to() outside is fine here
│ because there's no .output(n) selector inside .add()
│
├── Selector involved (.output(n) or composite handlers)?
│ └── .to() MUST go inside .add(). See "the trap" above
│
├── Targeting a specific input slot on a multi-input node (Merge)?
│ └── .add(source.output(n).to(target.input(m)))
│ AND check useDataOfInput. See references/MERGE_INDEX_RULES.md
│
├── Error branch?
│ └── .add(node.output(1).to(handler))
│ AND set onError: 'continueErrorOutput' on the node config.
│ See references/ERROR_OUTPUTS.md
│
└── Fan-out (one source → many targets) or fan-in (many sources → one target)?
└── See references/FAN_OUT_FAN_IN.md要配置连接?
├── 线性连接(一个源节点 → 一个目标节点,单输出、单输入)?
│ └── 使用.add(source).to(target)。这种简单场景下,.to()放在外面没问题
│ 因为.add()内部没有.output(n)选择器
│
├── 涉及选择器(.output(n)或复合处理器)?
│ └── .to()必须放在.add()内部。参见上方的“陷阱”部分
│
├── 要定位多输入节点(如Merge)的特定输入槽?
│ └── 使用.add(source.output(n).to(target.input(m)))
│ 并检查useDataOfInput配置。参见参考文档/MERGE_INDEX_RULES.md
│
├── 错误分支?
│ └── 使用.add(node.output(1).to(handler))
│ 并在节点配置中设置onError: 'continueErrorOutput'。
│ 参见参考文档/ERROR_OUTPUTS.md
│
└── 扇出(一个源节点 → 多个目标节点)或扇入(多个源节点 → 一个目标节点)?
└── 参见参考文档/FAN_OUT_FAN_IN.mdComposite handlers (.onTrue
, .onFalse
, .onCase
, .onError
)
.onTrue.onFalse.onCase.onError复合处理器(.onTrue
、.onFalse
、.onCase
、.onError
)
.onTrue.onFalse.onCase.onErrorThe SDK provides convenience handlers on IF, Switch, and any node with an error output:
ts
.add(ifNode.onTrue(targetA)) // same as .add(ifNode.output(0).to(targetA))
.add(ifNode.onFalse(targetB)) // same as .add(ifNode.output(1).to(targetB))
.add(sw.onCase(2, target)) // same as .add(sw.output(2).to(target))
.add(node.onError(handler)) // same as .add(node.output(1).to(handler))These compose with calls without conflict.
.output(n)ts
.add(ifNode.onTrue(targetA))
.add(ifNode.output(0).to(targetB))
// Result: BOTH targetA and targetB on IF's main[0]. Composite + .output(n) merge.The only shape to avoid is the trap above. That's always wrong, regardless of whether a composite handler ran earlier.
.add(selector).to(target)SDK为IF、Switch以及任何带有错误输出的节点提供了便捷处理器:
ts
.add(ifNode.onTrue(targetA)) // 等同于.add(ifNode.output(0).to(targetA))
.add(ifNode.onFalse(targetB)) // 等同于.add(ifNode.output(1).to(targetB))
.add(sw.onCase(2, target)) // 等同于.add(sw.output(2).to(target))
.add(node.onError(handler)) // 等同于.add(node.output(1).to(handler))这些处理器可以和调用组合使用,不会产生冲突。
.output(n)ts
.add(ifNode.onTrue(targetA))
.add(ifNode.output(0).to(targetB))
// 结果:IF节点的主输出[0]同时连接到targetA和targetB。复合处理器 + .output(n)会合并连接。唯一需要避免的写法就是上面提到的陷阱。无论之前是否使用过复合处理器,这种写法都是错误的。
.add(selector).to(target)After every create or update: verify
创建或更新后的必做步骤:验证
validate_workflowcreate_workflow_from_codeupdate_workflowget_workflow_detailsconnections- Each has the expected set of targets (fan-outs preserved, not collapsed).
main[i] - Merge inputs land on the right indices, and matches the wiring.
useDataOfInput - Error-output nodes have AND
onError: 'continueErrorOutput'wired to a handler.main[1]
If any check fails, the workflow is broken despite passing validation. Fix and re-update.
See for the full post-create checklist.
references/VERIFICATION.md即使连接缺失,仍会返回验证通过。在调用或后,使用拉取工作流并检查对象:
validate_workflowcreate_workflow_from_codeupdate_workflowget_workflow_detailsconnections- 每个包含预期的目标集合(扇出连接被保留,未被合并)。
main[i] - Merge节点的输入连接到正确的索引,且配置与连接匹配。
useDataOfInput - 带有错误输出的节点已设置,且
onError: 'continueErrorOutput'已连接到处理节点。main[1]
如果任何检查未通过,即使工作流通过了验证,实际也是损坏的。需要修复后重新更新。
完整的创建后检查清单请参见。
references/VERIFICATION.mdReference files
参考文档
Read the file that matches the situation. Don't read all of them:
| File | Read when |
|---|---|
| One source → many targets, or many sources → one target |
| Wiring a Merge node, or you see |
| Adding error handling on an individual node (not error workflow, that's |
| Just created or updated a workflow with non-trivial connections |
根据场景阅读对应的文档,无需全部阅读:
| 文件 | 阅读场景 |
|---|---|
| 一个源节点 → 多个目标节点,或多个源节点 → 一个目标节点 |
| 配置Merge节点,或在节点配置中看到 |
| 为单个节点添加错误处理(不是错误工作流,错误工作流请参考 |
| 刚创建或更新了包含复杂连接的工作流 |
Anti-patterns
反模式
| Anti-pattern | What goes wrong | Fix |
|---|---|---|
| Wire silently dropped, validation passes | Move |
Mixing | Off-by-one, wire feeds the wrong input | Use |
Error branch wired without | Branch is unreachable, and node fails the whole workflow on error | Set |
Skipping | Silently broken workflows ship | Always pull and inspect after create/update |
| Reading all four reference files before wiring one connection | Wasted context | Read only the file matching the situation |
| 反模式 | 问题 | 修复方案 |
|---|---|---|
| 连接被静默丢弃,但验证通过 | 将 |
| 索引偏移,连接传入错误的输入 | 当 |
错误分支已连接,但未设置 | 分支无法访问,节点出错会导致整个工作流失败 | 在节点配置中设置 |
创建后跳过 | 损坏的工作流被静默发布 | 创建/更新后务必拉取并检查工作流 |
| 配置单个连接前阅读全部四份参考文档 | 浪费时间和精力 | 只阅读与当前场景匹配的文档 |