AI Operations 2026年3月22日 6 min read

n8n 自動化的實際踩坑筆記:那些文件沒說的事

用 n8n 打造一人公司自動化工作流的真實踩坑記錄,從 Content-Type 地獄到 Webhook 除錯,整理出可直接複用的避坑清單。

解鎖條件

你在 n8n 的 Canvas 上連好了所有節點,按下「Execute Workflow」,滿懷期待地等結果。

然後看到:Error: 400 Bad Request

你 Google 了三個小時,試了十幾種設定,Workflow 依然在某個莫名其妙的地方卡死。

這就是 n8n 的新手副本。不是它不好用——恰恰相反,n8n 是我用過最自由的自動化工具。但它的自由度也意味著:有一整座沒有地圖的地雷區等著你踩

這篇是我踩完之後,整理出來給自己用的避坑手冊。


坑一:Content-Type 地獄

這是我花最多時間的坑,也是最沒有必要踩的坑。

場景是這樣的:我要從 n8n 的 HTTP Request 節點發送資料到一個外部 API(例如我自己的 Next.js webhook)。資料格式長這樣:

{
  "order_id": "123",
  "customer_name": "Penso",
  "items": ["草莓塔", "芒果千層"]
}

看起來很直觀,對吧?節點填好、資料填好、發送。

結果收到端一直回 400,或者更糟——收到端收到的欄位全是空的

根本原因是:n8n 的 HTTP Request 節點,預設行為不是你以為的那個行為

具體來說:

  • 你以為你填的是 JSON body,但 n8n 可能把它當作 form-datax-www-form-urlencoded 送出去
  • 即使你選了 JSON,如果對方 API 要求 application/json 的 header,你還需要手動加 Header,不會自動帶上
  • 更詭異的是:某些版本的 n8n,Body ParametersJSON/RAW Body 的行為完全不同,但 UI 長得很像,很容易選錯

我的修復方式

凡是對接 JSON API,一律進入節點的 Headers 手動加:

Content-Type: application/json

並且在 Body 區段選擇 Raw > JSON,自己手寫 JSON 字串(可用 n8n 的表達式語法 {{ }} 插入動態值)。

這個習慣建立之後,80% 的 400 錯誤消失了。


坑二:Webhook 節點的雙重人格

n8n 的 Webhook 節點有兩個 URL:Test URLProduction URL

這本來是個好設計——開發時用 Test URL,可以直接在 Canvas 看到收到的資料;上線後改成 Production URL,Workflow 在背景跑。

問題出在:你忘了切換

或者更準確地說:你的外部服務(例如 LINE Messaging API、Discord Webhook、ManyChat)已經設定好 Production URL,但你的 n8n Workflow 還在 Test 模式跑——這時候,外部發過來的資料永遠不會被處理。

更糟的狀況是:Workflow 明明「看起來在執行」,但沒有任何 execution log 出現。你以為是外部服務的問題,花了半小時除錯,最後發現是 Workflow 根本沒被觸發。

我的 SOP

每次部署新 Workflow 前,先確認以下三件事:

  1. Webhook 節點已切換到 Production 模式
  2. Workflow 右上角已點擊 Activate(開關是藍色)
  3. 外部服務填的是 Production URL,不是 Test URL

聽起來很基本,但當你同時維護五個以上的 Workflow,這三個步驟漏掉任何一個,你都會有一段「明明設好了為什麼沒動」的迷失時光。


坑三:表達式語法的陷阱

n8n 的 {{ }} 表達式語法是它最強大的功能之一,讓你可以在任何欄位引用上游節點的資料。

但它有幾個不直觀的行為:

陷阱 A:引用路徑的層級問題

當上游節點輸出的資料結構是:

{
  "body": {
    "customer": {
      "name": "Penso"
    }
  }
}

你以為可以這樣寫:{{ $json.customer.name }}

但實際上要寫:{{ $json.body.customer.name }}

n8n 的 $json 指向的是整個節點輸出的 json 物件,不是你「以為的那個層」。每次卡住,先去節點的輸出面板確認真實的資料結構,不要靠直覺猜路徑。

陷阱 B:空值不會報錯,只是靜靜消失

如果你寫的路徑不存在,n8n 表達式不會丟出錯誤——它只會輸出空字串或 undefined,然後繼續往下跑。

結果就是:下游節點收到的是空值,但整個 Workflow 顯示「執行成功」。你要去 execution log 逐一看每個節點的輸入輸出,才能找到是哪一層沒拿到資料。

我的習慣:開發新 Workflow 時,在每個關鍵節點後面臨時插一個 Set 節點,把重要欄位 log 出來,確認資料流正確後再移除。


Before / After:一個真實案例

Before(踩坑版)

甜點訂單 → ManyChat 觸發 → n8n Webhook → HTTP Request → Discord 通知

結果:Discord 完全沒收到通知。花了兩小時才發現:Webhook 在 Test 模式、Content-Type 沒設、Discord API 要求 JSON body 但我送出的是 form-data。三個坑同時踩。

After(修復版)

  • Webhook 切 Production 並 Activate
  • HTTP Request 節點加 Content-Type: application/json header
  • Body 改用 Raw JSON + 表達式動態帶入訂單資料

結果:從觸發到 Discord 收通知,整個流程 3 秒內完成,穩定運行至今。


收斂反思

n8n 的學習曲線不在於「會不會用」,而在於你知不知道自己不知道什麼

文件寫得很完整,但它告訴你的是「這個節點可以做什麼」,不會告訴你「你以為可以這樣做,但其實不行」。

那些知識只存在踩過坑的人腦袋裡。

這篇就是我的腦袋外化版本。下次有 Workflow 卡關,先對照這份清單過一遍,能省掉至少 60% 的除錯時間。

如果你也有踩過其他坑,歡迎回覆告訴我——這份清單打算持續更新。

More logs are being generated from the Penso-OS source of truth.

Back to logs