A scan loop fired 10 phantom webhooks — here's how we found and killed every stale claim
Scheduling a print-shop video (bo-cong-cu-xuong-in) revealed a hidden bug: a prior scan loop had called the n8n VID-05 and VID-09 webhooks 5× each with placeholder captions. Each call created a real waiting execution AND locked a Dedup Guard slot claim in workflow staticData. Deleting the executions was not enough — the claims lived on. This explainer walks through the full repair chain and the 5 rules to prevent it from happening again.
6-layer thinking chainChuỗi tư duy 6 tầng
"ok" — user approved applying the cross-platform stagger for bo-cong-cu-xuong-in: YT Jun 30 (keep), IG Jul 3, FB Jul 5.
How the Dedup Guard system works
The Dedup Guard is a slot-locking mechanism inside VID-05 (IG) and VID-09 (FB). When a webhook arrives, the guard checks `staticData.claims` — a dict of platform|date|time keys. If the slot is free, it writes a claim and parks the execution at a 'Wait Until Due' node until publish time. The critical insight: claims are written immediately on entry, not at publish time. This means even a phantom webhook with placeholder data claims a slot for weeks.
| Technical termThuật ngữ kỹ thuật | Plain nameTên dễ hiểu | RoleVai trò |
|---|---|---|
staticData.claims | The slot-lock ledger | Global dict in workflow staticData. Key = platform|date|HH:MM. Written on execution entry, NOT cleared by execution deletion. |
Wait Until Due node | The 'park until publish time' node | n8n pauses the execution here until the scheduled dueAt. These executions are invisible to the standard list API. |
idemKey | Duplicate-content guard | Second dedup layer: FB uses slug|fb|date, IG uses media:{video_url}. Prevents same video posting twice even if slot guard fails. |
n8n_update_full_workflow | The only way to patch staticData | Must fetch full workflow JSON (mode=full), mutate staticData.claims in memory, then push the whole object back. Partial-update tool has no staticData operation type. |
Read the diagram top to bottom: every POST to a VID webhook immediately writes a slot claim to the global ledger, then parks the execution. If you delete the execution later, the claim stays in the ledger — it's a separate data store. That's why 10 deletions weren't enough; we also had to patch the ledger directly via n8n_update_full_workflow.
Repair sequence (in order)
Layered decision cardsCác quyết định theo tầng
Artifact mapBản đồ tệp tạo ra
| PathĐường dẫn | WhatLà gì | Who reads itAi dùng |
|---|---|---|
~/beup-workspace/content/calendar-data.json | Split bo-cong-cu-xuong-in-0630 into 3 per-platform entries (yt-0630 / ig-0703 / fb-0705) | Source of truth for scheduled content calendar |
n8n VID-09 staticData (workflow cUxRU6AhqjhaYUoT) | Removed 5 ghost FB claims (Jun 30, Jul 3/4/7/8 at 21:00). Kept 25 legitimate claims. | Dedup Guard for Facebook video scheduler |
n8n VID-05 staticData (workflow OQy1tmH23TGAuXmo) | Removed 5 ghost IG claims (Jun 30, Jul 3/4/7/8 at 20:00). Kept 25 legitimate claims. | Dedup Guard for Instagram Reel scheduler |
memory/n8n_dedup_guard_scheduling_lessons.md | 5 durable rules about n8n staticData, waiting executions, and Dedup Guard behaviour | Auto-memory system — loaded in future sessions |