我發佈這個是因為它花了我幾個小時,而且它無聲地失敗,這是最糟糕的組合。如果你通過 IF 或 Switch 節點路由任何重要的東西在布爾值上,這值得你花十分鐘的時間。
有一些開放的問題和論壇主題描述這種行為,但沒有附加根本原因。這是我發現的。
症狀
我有一個 Switch 節點決定是否發送警報。上游節點的輸出看起來像這樣:
{ “shouldEscalate”: true }
Switch condition: value:
{{ $(‘Extract Response’).first().json.shouldEscalate }}
operator: Boolean → is true
每次執行都路由為 false。沒有錯誤。執行報告成功。警報就是永遠不會觸發。
不是什麼
我一開始在錯誤的假設上浪費了時間,所以這裡列出來為了節省你的時間:
• 不是 .first() 對比 .item — 我檢查過了
• 不是多運行/項目系統問題
• 不是上游節點產生錯誤的值
我通過在 Switch 前直接放置一個 Set 節點來證明最後一點,該節點發出原始值加其類型:{ “val”: true, “type”: “boolean”, “runs”: 1 }
真正的布爾值。單次運行。正確的值到達節點。Switch 仍然發送它為 false。
真正的原因
n8n 將 {{ }} 表達式輸出呈現為文字。所以真實的布爾值 true 以字符串 “true” 的形式到達運算符 — 如果在參數欄位中的結束 }} 之後有任何尾部空格或換行符(粘貼時很容易引入),你會得到 "true "。
嚴格的 Boolean 運算符得到 "true ",這不是布爾值,比較失敗。靜默地,向 false 方向失敗。
最終節點逐字表面它: Wrong type: 'true ’ is a string but was expecting a boolean
為什麼明顯的修復沒有起作用
我嘗試在表達式內轉換:
{{ String($(‘Extract Response’).first().json.shouldEscalate).trim().toBoolean() }}
仍然失敗。空格不在表達式內 — 它在 n8n 自己的呈現過程中在 }} 之後引入。你在大括號內做的任何事都無法到達它。
切換「在需要時轉換類型」會改變失敗模式而不是修復它。在我的情況下,一個設置將所有內容路由為 true,另一個將所有內容路由為 false。兩者都是錯誤的;一個只是更明顯。
有效的修復
停止比較布爾值。發出一個明確的關鍵字並在文字上匹配:
value: {{ $(‘Extract Response’).first().json.shouldEscalate ? “ESCALATE” : “NORMAL” }}
operator: String → contains
match: ESCALATE
convert types: off
"ESCALATE " 仍然包含 “ESCALATE”。"NORMAL " 無論哪種方式都不包含它。尾部空格變成無害的而不是致命的。
在同一個構建上的兩個方向上驗證 — 條件 true 路由 true,條件 false 路由 false。值得雙向測試;僅測試你期望的方向是半個測試,這個 bug 特別能夠在一個方向上通過而在另一個方向上失敗。
通用版本
如果 Switch 或 IF 節點做出的決定真的很重要 — 警報、升級、合規門控、任何靜默走錯分支代價高昂的地方 — 不要在原始布爾值上路由它。呈現一個標記字符串並在其上匹配。
「這裡的失敗模式不是錯誤。它是做了錯誤事情的綠色執行。」