fix(a2a-queue): use partial-index ON CONFLICT syntax (not constraint name)

#1892's EnqueueA2A INSERT used `ON CONFLICT ON CONSTRAINT idx_a2a_queue_idempotency
DO NOTHING`, but Postgres rejects this:

  ERROR: constraint "idx_a2a_queue_idempotency" for table "a2a_queue" does not exist

Partial unique INDEXES cannot be referenced by name in ON CONFLICT — that
form is reserved for true CONSTRAINTs created via CREATE TABLE ... CONSTRAINT
or ALTER TABLE ADD CONSTRAINT. Partial indexes need the column-list +
WHERE form so the planner can match the index.

Effect of the bug: every EnqueueA2A errored, the busy-error fallback
returned 503 instead of 202, queue stayed empty. Cycle 50 observed
46 busy errors / 0 queue rows — the deployed Phase 1 had no effect.

Fix: switch to

  ON CONFLICT (workspace_id, idempotency_key)
    WHERE idempotency_key IS NOT NULL AND status IN ('queued','dispatched')
    DO NOTHING

Verified manually against the live `a2a_queue` table on staging — INSERT
returns the new id; cleanup deleted the test row.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
rabbitblood 2026-04-23 14:22:13 -07:00
parent 4e4ee610a7
commit 751b265dbd

View File

@ -82,13 +82,18 @@ func EnqueueA2A(
methodArg = method
}
// INSERT ... ON CONFLICT DO NOTHING RETURNING id. On conflict we then
// look up the existing row's id so the caller always receives a valid
// queue entry reference.
// INSERT ... ON CONFLICT DO NOTHING RETURNING id. The conflict target
// must reference the partial unique INDEX columns + WHERE clause directly
// (Postgres can't reference partial unique indexes by name in
// ON CONFLICT — only true CONSTRAINTs work for that). On conflict we
// then look up the existing row's id so the caller always receives a
// valid queue entry reference.
err = db.DB.QueryRowContext(ctx, `
INSERT INTO a2a_queue (workspace_id, caller_id, priority, body, method, idempotency_key)
VALUES ($1, $2, $3, $4::jsonb, $5, $6)
ON CONFLICT ON CONSTRAINT idx_a2a_queue_idempotency DO NOTHING
ON CONFLICT (workspace_id, idempotency_key)
WHERE idempotency_key IS NOT NULL AND status IN ('queued','dispatched')
DO NOTHING
RETURNING id
`, workspaceID, callerArg, priority, string(body), methodArg, keyArg).Scan(&id)