Summary
Publishing an event without metadata fails to persist when Outpost uses the Postgres log store. The event insert is rejected by Postgres and the log worker retries forever:
insert events failed: ERROR: null value in column "metadata" of relation "events_default" violates not-null constraint (SQLSTATE 23502)
Events (and their attempts) never become queryable. ClickHouse log store is unaffected.
Root cause
events.metadata is jsonb NOT NULL (since migration 000001_init). In internal/logstore/pglogstore/pglogstore.go, eventArrays() binds e.Metadata directly into the $8::jsonb[] insert param:
metadatas[i] = e.Metadata // nil when the event has no metadata
A published event with no metadata has Metadata == nil (a nil map[string]string). With pgx v5.10.0 a nil map element in a jsonb[] array encodes to SQL NULL, which violates the NOT NULL column → insert fails. The same applies to attemptArrays() → attempts.event_metadata (also NOT NULL).
Why it regressed now
Reproduction
Run spec-sdk-tests against an Outpost configured with the Postgres log store (this is what the spec-sdk-tests CI workflow does). The 3 event/attempt tests in Events (PR #491) time out:
should list events by tenant
publishing an event ... should generate an attempt
listAttempts with include=event.data ...
Confirmed locally with LOCAL_DEV_POSTGRES=1 + postgres: log store in .outpost.yaml — identical failure and Postgres error.
Fix
Default nil metadata to an empty map before binding, in both eventArrays() and attemptArrays():
metadata := e.Metadata
if metadata == nil {
metadata = map[string]string{}
}
metadatas[i] = metadata
Verified locally: with this change the suite goes back to 153 passing / 15 pending / 0 failing and the log worker logs no metadata errors.
Notes
🤖 Generated with Claude Code
Summary
Publishing an event without
metadatafails to persist when Outpost uses the Postgres log store. The event insert is rejected by Postgres and the log worker retries forever:Events (and their attempts) never become queryable. ClickHouse log store is unaffected.
Root cause
events.metadataisjsonb NOT NULL(since migration000001_init). Ininternal/logstore/pglogstore/pglogstore.go,eventArrays()bindse.Metadatadirectly into the$8::jsonb[]insert param:A published event with no metadata has
Metadata == nil(a nilmap[string]string). With pgx v5.10.0 a nil map element in ajsonb[]array encodes to SQLNULL, which violates theNOT NULLcolumn → insert fails. The same applies toattemptArrays()→attempts.event_metadata(alsoNOT NULL).Why it regressed now
v5.7.6 → v5.10.0in chore(deps): refresh Go dependencies #940 (dep refresh). Older pgx encoded the nil map as{}; v5.10 encodes it as SQLNULL.spec-sdk-testsrun (2026-06-19, 153 passing / 15 pending) predates chore(deps): refresh Go dependencies #940; the first red run is post-chore(deps): refresh Go dependencies #940 (149 passing / 16 pending / 3 failing).Reproduction
Run
spec-sdk-testsagainst an Outpost configured with the Postgres log store (this is what thespec-sdk-testsCI workflow does). The 3 event/attempt tests inEvents (PR #491)time out:should list events by tenantpublishing an event ... should generate an attemptlistAttempts with include=event.data ...Confirmed locally with
LOCAL_DEV_POSTGRES=1+postgres:log store in.outpost.yaml— identical failure and Postgres error.Fix
Default nil metadata to an empty map before binding, in both
eventArrays()andattemptArrays():Verified locally: with this change the suite goes back to 153 passing / 15 pending / 0 failing and the log worker logs no metadata errors.
Notes
🤖 Generated with Claude Code