Repository navigation
Store API: how should Add Line Item be retried safely after a lost response? #17796
Replies: 1 comment
|
Additional evidence: I have now reproduced a mutation completing after a real client/transport timeout, rather than only discarding an already successful response. Environment: Medusa/framework 2.22.6, Node.js 24.22.2, fresh PostgreSQL 18.6 database. The backend source/config/seed were unchanged from the official This test used isolated copies of our actual nginx configuration and built Node/Astro application. The application calls the Store API through its normal strict HTTP transport, with a 10-second timeout and no retries. No extra test proxy was inserted into that path. A successful control request first created a cart with quantity 1, using the actual application action and its signed proof/session cookies. To make the ordering deterministic:
Results on two separate carts:
In both cases, the late quantity change was observed about 52 ms after releasing the lock. Medusa's HTTP logs show exactly one
Limits: this was an isolated HTTP integration test with a synthetic test publication/configuration and a fresh database, not a browser UI test or a purchase against an existing deployment. It did not test checkout, payments, price/stock races, or whether a retry would be deduplicated in this second experiment. The original replay experiment above covers that separately. The contract question remains: is there a supported operation key or operation-status mechanism for safely resolving/retrying an Add Line Item request after this ambiguous outcome? I am still treating this as a contract/feature request, not as proof that the route violates a documented |
Uh oh!
There was an error while loading. Please reload this page.
Contract question / feature request
Does
POST /store/carts/:id/line-itemssupport an operation key that makes retryingafter a lost response safe? In the reproduction below, repeating the same request
with the same
Idempotency-Keyincreases the quantity again.If this header is not supported by this route, is there a recommended mechanism
for recovering an operation's outcome or retrying it without another increment?
If not, would you consider adding one and documenting the retry contract?
I am not claiming that this violates an existing documented guarantee. The
storefront guide
describes
quantityas the quantity to add; I did not find a guarantee that thisroute honors
Idempotency-Key.Environment
@medusajs/medusa: 2.22.6.@medusajs/framework: 2.22.6.dtc-starterat 6440e853ee091b5ddc431aa2680dd358985aa707,including its config, seed, search, routes and workflows. All 24 files under
src, plus the config/package files included in that count, matched theofficial source archive by SHA-256.
was not an independent clean dependency installation.
?sslmode=disablebecause that isolatedPostgreSQL instance does not support SSL. No pool settings or source files were
changed. The successful run used no diagnostic preload.
fetch, without ourapplication code or an SDK. No checkout or payment operation is involved.
Steps to reproduce
Use a disposable instance with a priced variant that has at least three available
units. Create a cart with one unit of that variant.
Send the following request, substituting the cart, variant and publishable key:
the caller, and throw a simulated response-loss error instead.
Idempotency-Key.The standalone Node.js script below automates these steps and verifies each
observed quantity. It creates one cart and adds three units, so it should only
be run against a disposable database. Set
MEDUSA_URL,MEDUSA_PUBLISHABLE_KEY,MEDUSA_REGION_ID, and optionallyMEDUSA_SALES_CHANNEL_ID.Observed result
Both POST requests returned HTTP 200. Subsequent GET requests confirmed both
increments. The script returns diagnostic exit code 2 when replay increments
again, and 0 if the replay is deduplicated.
Desired contract
If an operation key is supported, replaying a completed operation should return
its outcome, or provide a way to query that outcome, without another mutation.
In this example, the quantity would remain 2.
It would help to clarify the key's scope and retention period, how a changed
request body is handled, and what happens with concurrent retries. These are
requested semantics, not assertions that the route currently promises them.
Disabling automatic retries avoids some duplicates but leaves the user with an
unknown outcome after response loss. Reading the cart does not always identify
which operation caused a quantity change when multiple tabs or concurrent actions
are involved.
Limits of this reproduction
Response loss is simulated deterministically after the first request has
completed successfully. This is not a real connection interruption or timeout
test, and it does not establish late server-side completion after cancellation.
It does not test price/stock races, cart-creation replay, checkout or payments.
Standalone reproduction script
All reactions