dispatcher creates a DUPLICATE system webhook on every boot (Forgejo admin-hooks LIST returns [] while the hooks exist) #63
Labels
No labels
bug
discussion
duplicate
enhancement
goal
help wanted
horizon:backlog
horizon:governance
horizon:mvp
invalid
operator-decision
question
roadmap
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
open-platform/mitosis#63
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found while validating a fresh wb-gate germination (plat.local, Forgejo 15.0.0+gitea-1.22.0, agents 0.7.5).
ensureWebhookboot idempotency is list-based:listAdminHooks()→ find by URL → create if absent (agents src/dispatcher.ts ~3162). On this Forgejo,GET /api/v1/admin/hooksreturns[]under EVERY variant (?type=system,?type=default, none) even though the hook EXISTS and FIRES —GET /api/v1/admin/hooks/1returns it fine. Somineis never found and every dispatcher boot creates another system hook. PROVEN LIVE: onerollout restart→ hooks id 1 AND id 3, same dispatcher URL, both active → every Forgejo event delivers twice (doubled runs/noise; RBAC-5 re-apply can never patch either). Fix direction (version-agnostic, uses the endpoint that demonstrably works): persist the created hook id in dispatcher state (/data survives restarts); on boot GET/admin/hooks/{id}directly → patch (re-applies the sealed HMAC secret per RBAC-5) → create+store only on 404; best-effort delete any listed hook with our URL that is notstate.webhookId. Interim operator remediation: probe ids andDELETE /api/v1/admin/hooks/<dup>.Fix open: plat/agents#10 — webhook idempotency by persisted id (verify via
GET /admin/hooks/{id}, which answers truthfully; adopt-by-list when the list works; best-effort duplicate reap). Regression-tested (two-boots-with-lying-list) and client paths validated against the live Forgejo 15 on plat.local. The duplicate hook on plat.local was removed by hand (DELETE /admin/hooks/3).plat referenced this issue2026-07-02 04:02:40 +00:00
Prod (0.7.6 rollout) follow-through: first boot with empty dispatcher state + the lying LIST took the create path as designed → new owned hook id 182 alongside the legacy id 1 → double-delivery for ~9h. Applied the documented remediation: deleted the unowned id 1; id 182 verified sole + persisted in state (future boots take the verify path — confirmed on val076). Fresh germinations are immune (create-once + persist). Upstream note:
GET /api/v1/admin/hooksreturning [] while hooks exist reproduces on Forgejo 15.0.0+gitea-1.22.0 — worth an upstream report; the dispatcher no longer depends on it either way.Fixed in agents v0.7.6 (plat/agents#10 → release #13). Idempotency by persisted hook id; validated on val076 (restart → still one hook, verify path) and remediated live on prod (deleted legacy id 1; owned id 182 sole). Closing.