fix: resolve remaining webhook schema issues in multi-tenant retain (#533)

Follow-up to #499 which fixed the worker path and http.py but missed
two code paths in memory_engine.py:

1. `_retain_batch_async_internal` (line ~2185) still passed
   `request_context.tenant_id` which is always None for HTTP requests
   (tenant_id is never populated by the HTTP layer — the schema is
   stored in the _current_schema contextvar by _authenticate_tenant).

2. `_build_retain_outbox_callback._callback` captured the `schema`
   parameter at closure creation time. In the HTTP path, http.py builds
   the callback *before* calling retain_batch_async, but _current_schema
   is only set inside retain_batch_async by _authenticate_tenant — so
   the captured schema is always None. Fixed by resolving schema at
   callback invocation time via `schema or _current_schema.get()`.

Both issues cause `relation "webhooks" does not exist` errors that
abort the entire retain transaction in multi-tenant deployments,
silently rolling back all inserted memory data.
This commit is contained in:
And#ocean 2026-03-10 18:44:04 +03:00 committed by GitHub
parent cd3a6a227b
commit 32a4882a10
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1139,8 +1139,13 @@ class MemoryEngine(MemoryEngineInterface):
)
async def _callback(conn: asyncpg.Connection) -> None:
# Resolve schema at call time (not at callback creation time) because
# _current_schema contextvar may not yet be set when the callback is built
# from the HTTP path (http.py calls _build_retain_outbox_callback before
# retain_batch_async which is where _authenticate_tenant sets the schema).
resolved_schema = schema or _current_schema.get()
for event in events:
await webhook_manager.fire_event_with_conn(event, conn, schema=schema)
await webhook_manager.fire_event_with_conn(event, conn, schema=resolved_schema)
return _callback
@ -2182,7 +2187,7 @@ class MemoryEngine(MemoryEngineInterface):
document_tags=document_tags,
config=resolved_config,
operation_id=operation_id,
schema=request_context.tenant_id if request_context else None,
schema=_current_schema.get(),
outbox_callback=outbox_callback,
)