Discord Username / User ID
interferon0
What does this improvement do?
The HTTP client's transport-retry paths (network error, and bare 408/502/504) fire for ANY method, but the plain post/put/patch/delete helpers do not send an Idempotency-Key. So a response lost after the server committed it (a 502 from the edge on the response leg, or a socket reset) triggers a blind replay that can create a duplicate project, a duplicate test, or a second /tests/batch creation, costing credits and polluting the project. Gate the transport retries so a write without an idempotency key is not blindly replayed.
Details / implementation notes
The retries are at src/lib/http.ts:467 (network error) and :530 (408/502/504); the dedicated trigger helpers DO send idempotency-key (http.ts:241, 269, 292, 311, 331) but the generic mutation helpers do not (call sites: project.ts:233, test.ts:803/2120/2428, delete at 1387/1634). Minimal fix: only auto-retry when method === 'GET' || method === 'HEAD' OR an idempotency-key header is present. Cleaner long-term: have the generic post/put/patch/delete mint an idempotency key by default. No new dependency. Tests: a transport error on a keyless POST is not retried; a GET or a keyed write still retries. PR to follow once assigned.
Confirmations
Discord Username / User ID
interferon0
What does this improvement do?
The HTTP client's transport-retry paths (network error, and bare 408/502/504) fire for ANY method, but the plain post/put/patch/delete helpers do not send an Idempotency-Key. So a response lost after the server committed it (a 502 from the edge on the response leg, or a socket reset) triggers a blind replay that can create a duplicate project, a duplicate test, or a second /tests/batch creation, costing credits and polluting the project. Gate the transport retries so a write without an idempotency key is not blindly replayed.
Details / implementation notes
The retries are at src/lib/http.ts:467 (network error) and :530 (408/502/504); the dedicated trigger helpers DO send idempotency-key (http.ts:241, 269, 292, 311, 331) but the generic mutation helpers do not (call sites: project.ts:233, test.ts:803/2120/2428, delete at 1387/1634). Minimal fix: only auto-retry when method === 'GET' || method === 'HEAD' OR an idempotency-key header is present. Cleaner long-term: have the generic post/put/patch/delete mint an idempotency key by default. No new dependency. Tests: a transport error on a keyless POST is not retried; a GET or a keyed write still retries. PR to follow once assigned.
Confirmations