From 751b265dbd15c5f06a1b38fd1516e10f45d02189 Mon Sep 17 00:00:00 2001 From: rabbitblood Date: Thu, 23 Apr 2026 14:22:13 -0700 Subject: [PATCH] fix(a2a-queue): use partial-index ON CONFLICT syntax (not constraint name) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #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) --- workspace-server/internal/handlers/a2a_queue.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/workspace-server/internal/handlers/a2a_queue.go b/workspace-server/internal/handlers/a2a_queue.go index 2bd30148..177d6b82 100644 --- a/workspace-server/internal/handlers/a2a_queue.go +++ b/workspace-server/internal/handlers/a2a_queue.go @@ -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)