Webhook deletion does not clean up deliveries and delivery results #24

Closed
opened 2026-03-02 01:29:21 +01:00 by clawbot · 0 comments
Collaborator

Bug

When a webhook is deleted via HandleSourceDelete() in source_management.go, the handler soft-deletes child entrypoints, targets, and events:

tx.Where("webhook_id = ?", webhook.ID).Delete(&database.Entrypoint{})
tx.Where("webhook_id = ?", webhook.ID).Delete(&database.Target{})
tx.Where("webhook_id = ?", webhook.ID).Delete(&database.Event{})
tx.Delete(&webhook)

But it does NOT clean up:

  • Deliveries (linked to events and targets)
  • DeliveryResults (linked to deliveries)

This leaves orphaned records in the database. Since Delivery references Event and Target by foreign key, and GORM uses soft deletes, the orphaned deliveries will reference soft-deleted parents, which can cause issues with the delivery engine (it queries for pending/retrying deliveries and tries to preload their targets and events).

Additionally, the delivery engine could attempt to process deliveries for a deleted webhook's targets, leading to errors or unintended behavior.

Fix

Also soft-delete related deliveries and results in the same transaction:

// Get event IDs for this webhook
var eventIDs []string
tx.Model(&database.Event{}).Where("webhook_id = ?", webhook.ID).Pluck("id", &eventIDs)

// Get delivery IDs for these events
var deliveryIDs []string
tx.Model(&database.Delivery{}).Where("event_id IN ?", eventIDs).Pluck("id", &deliveryIDs)

// Delete delivery results, deliveries, then events/targets/entrypoints/webhook
tx.Where("delivery_id IN ?", deliveryIDs).Delete(&database.DeliveryResult{})
tx.Where("event_id IN ?", eventIDs).Delete(&database.Delivery{})
tx.Where("webhook_id = ?", webhook.ID).Delete(&database.Event{})
tx.Where("webhook_id = ?", webhook.ID).Delete(&database.Target{})
tx.Where("webhook_id = ?", webhook.ID).Delete(&database.Entrypoint{})
tx.Delete(&webhook)

Category

Should-fix. Orphaned records cause data integrity issues.

## Bug When a webhook is deleted via `HandleSourceDelete()` in `source_management.go`, the handler soft-deletes child entrypoints, targets, and events: ```go tx.Where("webhook_id = ?", webhook.ID).Delete(&database.Entrypoint{}) tx.Where("webhook_id = ?", webhook.ID).Delete(&database.Target{}) tx.Where("webhook_id = ?", webhook.ID).Delete(&database.Event{}) tx.Delete(&webhook) ``` But it does NOT clean up: - **Deliveries** (linked to events and targets) - **DeliveryResults** (linked to deliveries) This leaves orphaned records in the database. Since Delivery references Event and Target by foreign key, and GORM uses soft deletes, the orphaned deliveries will reference soft-deleted parents, which can cause issues with the delivery engine (it queries for `pending`/`retrying` deliveries and tries to preload their targets and events). Additionally, the delivery engine could attempt to process deliveries for a deleted webhook's targets, leading to errors or unintended behavior. ## Fix Also soft-delete related deliveries and results in the same transaction: ```go // Get event IDs for this webhook var eventIDs []string tx.Model(&database.Event{}).Where("webhook_id = ?", webhook.ID).Pluck("id", &eventIDs) // Get delivery IDs for these events var deliveryIDs []string tx.Model(&database.Delivery{}).Where("event_id IN ?", eventIDs).Pluck("id", &deliveryIDs) // Delete delivery results, deliveries, then events/targets/entrypoints/webhook tx.Where("delivery_id IN ?", deliveryIDs).Delete(&database.DeliveryResult{}) tx.Where("event_id IN ?", eventIDs).Delete(&database.Delivery{}) tx.Where("webhook_id = ?", webhook.ID).Delete(&database.Event{}) tx.Where("webhook_id = ?", webhook.ID).Delete(&database.Target{}) tx.Where("webhook_id = ?", webhook.ID).Delete(&database.Entrypoint{}) tx.Delete(&webhook) ``` ## Category Should-fix. Orphaned records cause data integrity issues.
clawbot added the
bot
label 2026-03-02 01:29:21 +01:00
sneak closed this issue 2026-03-04 01:19:43 +01:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: sneak/webhooker#24
No description provided.