fix(webhooks): .any() auf JSONB-Spalte crashte jeden Event-Publish (158 failed Outbox-Events) #380

Closed
opened 2026-09-14 06:02:30 +00:00 by Leopoldadmin · 0 comments
Owner

Bug

Webhook.events ist ein JSONB-Array-Column (Migration 0042: events JSONB NOT NULL DEFAULT '[]'), KEINE Relationship. Trotzdem riefen zwei Stellen Webhook.events.any(event) auf — das existiert nur auf Relationship-Attributen:

  • app/core/webhook_dispatcher.py (Wildcard *-Handler, läuft bei jedem Outbox-Event)
  • app/services/webhook_service.py list_webhooks(event=...)

Folge: Jedes Event, das durch den Webhook-Dispatcher lief, crashte mit Neither 'AnnotatedColumn' nor 'Comparator' object has an attribute 'any' und wurde nach 4 Versuchen als failed markiert — 158 fehlgeschlagene Events (file.deleted vom 2026-08-27) in Produktion, sichtbar über die neue Outbox-UI (Modul 9).

Fix (Commit 50d6733)

JSONB-Containment statt Relationship-API an beiden Stellen:

cast(Webhook.events, JSONB).contains([event_name])  # events @> '["file.deleted"]'

Verifikation

  • Regressionstests: tests/test_webhooks.py 6/6 passed (3x Service-Event-Filter, 3x Dispatcher-Matching inkl. inactive/other-events-Fälle) — echte PostgreSQL-Test-DB, SQL beweist CAST(webhooks.events AS JSONB) @> ...
  • Full Deploy: Health 200, Alembic 0144, RLS 113
  • Live-Beweis: POST /outbox/replay-allreplayed_count: 158 → nach Worker-Verarbeitung: stats = {failed: 0, published: 158} (vorher: {failed: 158})

Gefunden über die neue Outbox-UI (Modul 9) — DLQ + Consumer-Registry machten den Fehler sichtbar.

## Bug `Webhook.events` ist ein **JSONB-Array-Column** (Migration 0042: `events JSONB NOT NULL DEFAULT '[]'`), KEINE Relationship. Trotzdem riefen zwei Stellen `Webhook.events.any(event)` auf — das existiert nur auf Relationship-Attributen: - `app/core/webhook_dispatcher.py` (Wildcard `*`-Handler, läuft bei **jedem** Outbox-Event) - `app/services/webhook_service.py list_webhooks(event=...)` **Folge:** Jedes Event, das durch den Webhook-Dispatcher lief, crashte mit `Neither 'AnnotatedColumn' nor 'Comparator' object has an attribute 'any'` und wurde nach 4 Versuchen als failed markiert — **158 fehlgeschlagene Events** (`file.deleted` vom 2026-08-27) in Produktion, sichtbar über die neue Outbox-UI (Modul 9). ## Fix (Commit 50d6733) JSONB-Containment statt Relationship-API an beiden Stellen: ```python cast(Webhook.events, JSONB).contains([event_name]) # events @> '["file.deleted"]' ``` ## Verifikation - **Regressionstests:** `tests/test_webhooks.py` 6/6 passed (3x Service-Event-Filter, 3x Dispatcher-Matching inkl. inactive/other-events-Fälle) — echte PostgreSQL-Test-DB, SQL beweist `CAST(webhooks.events AS JSONB) @> ...` - **Full Deploy:** Health 200, Alembic 0144, RLS 113 - **Live-Beweis:** `POST /outbox/replay-all` → `replayed_count: 158` → nach Worker-Verarbeitung: `stats` = `{failed: 0, published: 158}` (vorher: `{failed: 158}`) Gefunden über die neue Outbox-UI (Modul 9) — DLQ + Consumer-Registry machten den Fehler sichtbar.
Leopoldadmin added the bug label 2026-09-14 06:02:30 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Leopoldadmin/leocrm#380