[總管收錄] 引擎級:foreach 內 code 輸出餵 http/trigger 模板不展開(四寫法實證)+失敗節點不中斷下游 #64

Open
opened 2026-07-18 11:51:56 +00:00 by Leo · 1 comment
Owner

現象(2026-07-18 T-pack-v2 打包實撞,四種寫法逐一驗證)

foreach(A >> 對每個 x >> B)內,code 零件輸出餵給 http/trigger_workflow 的模板一律不展開,下游收到字面量字串 {{node.data.field}}

寫法 結果
http body_json 引用 code 輸出 {{clean_card.data.card_b64}} 字面量(Gitea 422 illegal base64 at input byte 0——byte 0 就是 {
http body(字串模式)引用 code 輸出 字面量/二次編碼
http URL 內引用 code 輸出 字面量(404)
trigger_workflow 的 input 引用 code 輸出 子流程收到字面量

同場另撞:

  • foreach 內 http body_json 直接 passthrough 一個物件引用("{{x.data.payload}}")會被字串化成 JSON 文字,不是物件。
  • 引擎越過失敗節點繼續跑:code 節點 return {success:false} 或炸掉後,下游 http 照跑,把未展開字面量一路帶到外部 API——錯誤被外部 4xx 掩蓋,排錯極貴。

foreach 內可靠的引用只有三種(實測):①迭代物件 {{x.field}} ②緊鄰 code→code ③http 節點輸出 {{node.data.body}}

影響

任何「foreach 內:code 加工 → http 寫出」的自然寫法都靜默壞掉。這是 RAG 萃取鏈(per-file:LLM 萃卡 → commit)最直覺的形狀,被迫改架構。

已用的繞法(可當回歸測例)

arcrun-rag 倉的「dispatcher+one」兩段式:foreach 只做 per-file 派發(body_json 全用迭代物件欄位),實工作放無 foreach 直鏈——workflows/rag-extract.local.yamlrag-extract-one.local.yaml;或讓迭代物件自帶全部欄位(rag-ingest-cards.local.yaml 的 rel 物件作法)。

建議

  1. foreach 執行上下文把已完成節點輸出納入模板解析範圍(與直鏈一致);做不到就在編譯期對「foreach 內引用非迭代來源」報錯,別靜默留字面量。
  2. 節點失敗預設中斷該 item 的下游(或至少把「帶著未解析模板打外部 API」擋下)。
  3. 順帶文件化:節點 id 會被編譯器強制小寫(stepAstepa,config 鍵對不上時報「找不到零件」,訊息誤導)。

(總管收錄;細節與再現紀錄在 arcrun-rag wiki mistakes.md 2026-07-18 四條)

## 現象(2026-07-18 T-pack-v2 打包實撞,四種寫法逐一驗證) **foreach(`A >> 對每個 x >> B`)內,code 零件輸出餵給 http/trigger_workflow 的模板一律不展開**,下游收到字面量字串 `{{node.data.field}}`: | 寫法 | 結果 | |---|---| | http `body_json` 引用 code 輸出 `{{clean_card.data.card_b64}}` | 字面量(Gitea 422 `illegal base64 at input byte 0`——byte 0 就是 `{`) | | http `body`(字串模式)引用 code 輸出 | 字面量/二次編碼 | | http URL 內引用 code 輸出 | 字面量(404) | | `trigger_workflow` 的 input 引用 code 輸出 | 子流程收到字面量 | 同場另撞: - foreach 內 http `body_json` 直接 passthrough 一個物件引用(`"{{x.data.payload}}"`)會被**字串化**成 JSON 文字,不是物件。 - **引擎越過失敗節點繼續跑**:code 節點 return `{success:false}` 或炸掉後,下游 http 照跑,把未展開字面量一路帶到外部 API——錯誤被外部 4xx 掩蓋,排錯極貴。 foreach 內**可靠**的引用只有三種(實測):①迭代物件 `{{x.field}}` ②緊鄰 code→code ③http 節點輸出 `{{node.data.body}}`。 ## 影響 任何「foreach 內:code 加工 → http 寫出」的自然寫法都靜默壞掉。這是 RAG 萃取鏈(per-file:LLM 萃卡 → commit)最直覺的形狀,被迫改架構。 ## 已用的繞法(可當回歸測例) arcrun-rag 倉的「dispatcher+one」兩段式:foreach 只做 per-file 派發(body_json 全用迭代物件欄位),實工作放無 foreach 直鏈——`workflows/rag-extract.local.yaml`+`rag-extract-one.local.yaml`;或讓迭代物件自帶全部欄位(`rag-ingest-cards.local.yaml` 的 rel 物件作法)。 ## 建議 1. foreach 執行上下文把已完成節點輸出納入模板解析範圍(與直鏈一致);做不到就在編譯期對「foreach 內引用非迭代來源」**報錯**,別靜默留字面量。 2. 節點失敗預設中斷該 item 的下游(或至少把「帶著未解析模板打外部 API」擋下)。 3. 順帶文件化:節點 id 會被編譯器強制小寫(`stepA`→`stepa`,config 鍵對不上時報「找不到零件」,訊息誤導)。 (總管收錄;細節與再現紀錄在 arcrun-rag wiki mistakes.md 2026-07-18 四條)
Leo added the
s
triage
label 2026-08-09 13:13:11 +00:00
Author
Owner

[總管·票務複驗 2026-08-09 晚] 這張我查不出來,標 s/triage 等實測,不敢說它好了也不敢說它壞著。

graph-executor.tsFOREACH case(:520-560)與 PIPE case(:440)現在走同一套 propagateCtx 合併機制,架構上理應與非-foreach 情境一致;t117(:540)只修了「foreach 全部項目失敗才拋錯」這一半。

找不到任何 commit 專門處理「foreach 內引用非相鄰節點模板不展開」這個症狀,也沒有人實跑過一個 foreach + code + http 的工作流去看票裡那四種寫法現在會怎樣。

⇒ 要收這張,需要真的跑一次(票裡四種寫法各一次),貼執行輸出。讀碼推不出答案。

[總管·票務複驗 2026-08-09 晚] **這張我查不出來,標 `s/triage` 等實測,不敢說它好了也不敢說它壞著。** `graph-executor.ts` 的 `FOREACH` case(:520-560)與 `PIPE` case(:440)現在走**同一套** `propagateCtx` 合併機制,架構上理應與非-foreach 情境一致;`t117`(:540)只修了「foreach 全部項目失敗才拋錯」這一半。 但**找不到任何 commit 專門處理「foreach 內引用非相鄰節點模板不展開」這個症狀**,也沒有人實跑過一個 `foreach + code + http` 的工作流去看票裡那四種寫法現在會怎樣。 ⇒ 要收這張,需要**真的跑一次**(票裡四種寫法各一次),貼執行輸出。讀碼推不出答案。
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Leo/Arcrun#64