fix(a2a-queue): use partial-index ON CONFLICT syntax (not constraint name) - #1893
Merged
Merged
Conversation
…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>
HongmingWang-Rabbit
added a commit
that referenced
this pull request
Apr 23, 2026
Cycle 53 found callers logging 45× 'delegation failed: proxy a2a error'
even though the queue's drain stats showed 48 completions in the same
window. Investigation: my busy-error path returned
return http.StatusAccepted, nil, &proxyA2AError{Status: 202, Response: ...}
The non-nil proxyA2AError is the failure signal. Even with status=202,
callers' `if proxyErr != nil` branch fires and logs the request as
failed. The 202 status was meaningless — the response body was nil too,
so the caller never even saw the queue_id/depth metadata.
Fix: return success-shape so callers do NOT enter the error branch:
respBody, _ := json.Marshal(gin.H{"queued": true, "queue_id": qid, ...})
return http.StatusAccepted, respBody, nil
Net effect: queue continues to absorb busy-errors (working since #1893),
AND callers correctly record the dispatch as queued-success rather than
failed. Closes the cycle 53 misclassification that was making the queue
look ineffective on activity_logs counts.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
molecule-ai Bot
added a commit
that referenced
this pull request
Apr 23, 2026
) (#1896) * fix(a2a-queue): nil-safe error extraction in DrainQueueForWorkspace + handle 202-requeue The drain path called proxyErr.Response["error"].(string) without a comma- ok assertion. When proxyErr.Response had no "error" key (which happens in the 202-Accepted-queued branch I added in the same PR — that response is {"queued": true, "queue_id": ..., "queue_depth": ...}), the type assertion panicked and killed the platform process. The platform was down 25 minutes today before this was diagnosed. Fleet went from 30 real outputs/15min → 0 events. Two fixes here: 1. Treat 202 Accepted from the inner proxyA2ARequest as "re-queued" (target was busy AGAIN). Mark THIS attempt completed; the new queue row will be drained on the next heartbeat tick. Don't propagate as failure. 2. Defensive type-assertion when reading the error string. Falls back to http.StatusText, then a generic "unknown drain dispatch error" so the queue still gets a non-empty error_detail for ops debugging. Now the drain path can never panic on a malformed proxy response. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(a2a-queue): return (202, body, nil) so callers see queued-as-success Cycle 53 found callers logging 45× 'delegation failed: proxy a2a error' even though the queue's drain stats showed 48 completions in the same window. Investigation: my busy-error path returned return http.StatusAccepted, nil, &proxyA2AError{Status: 202, Response: ...} The non-nil proxyA2AError is the failure signal. Even with status=202, callers' `if proxyErr != nil` branch fires and logs the request as failed. The 202 status was meaningless — the response body was nil too, so the caller never even saw the queue_id/depth metadata. Fix: return success-shape so callers do NOT enter the error branch: respBody, _ := json.Marshal(gin.H{"queued": true, "queue_id": qid, ...}) return http.StatusAccepted, respBody, nil Net effect: queue continues to absorb busy-errors (working since #1893), AND callers correctly record the dispatch as queued-success rather than failed. Closes the cycle 53 misclassification that was making the queue look ineffective on activity_logs counts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: molecule-ai[bot] <276602405+molecule-ai[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
[molecule-platform-evolvement-manager-agent]
Hot-fix for #1892. The EnqueueA2A INSERT silently errored on every call because Postgres rejects
ON CONFLICT ON CONSTRAINT <name>for partial unique INDEXES — that form only works for true CONSTRAINTs.The busy-error fallback in
a2a_proxy_helpers.gomasked this — when EnqueueA2A returned err, the code logged + fell through to the legacy 503. So Phase 1 deployed silently broken: 0 queue rows in 15min vs 46 busy errors.Fix: switch to the partial-index form
Verified locally on the live staging
a2a_queuetable — INSERT returns the new id, conflict is properly handled.Already deployed to local staging via direct platform rebuild, this PR is just to land the source-of-truth fix on the branch.
🤖 Generated with Claude Code