Skip to content

fix(checkout-api): resolve checkout-race-condition#7

Open
Spkap wants to merge 1 commit intomainfrom
replayx/incident-checkout-race-001-mo64d7d0
Open

fix(checkout-api): resolve checkout-race-condition#7
Spkap wants to merge 1 commit intomainfrom
replayx/incident-checkout-race-001-mo64d7d0

Conversation

@Spkap
Copy link
Copy Markdown
Collaborator

@Spkap Spkap commented Apr 19, 2026

Summary

Resolve checkout-race-condition for checkout-api with a validated ReplayX patch candidate.

Changed Files

  • demo_app/src/inventory/reserve-stock.ts
  • demo_app/src/checkout/submit-order.ts

Validation

  • Concurrent checkout repro: exit 0
  • Sequential checkout sanity: exit 0

Rollback

Revert the live inventory guard and concurrent checkout settlement handling.

Copilot AI review requested due to automatic review settings April 19, 2026 18:48
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Resolves the checkout race condition by preventing overselling during concurrent reservations and making the concurrent checkout scenario treat expected out-of-stock outcomes as non-fatal.

Changes:

  • Add a post-delay (commit-time) availability check in reserveStock to prevent stale pre-checks from overselling.
  • Return reservation metadata based on the committed inventory record version.
  • Update concurrent checkout scenario execution to use Promise.allSettled and ignore expected out-of-stock failures.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
demo_app/src/inventory/reserve-stock.ts Adds commit-time inventory guard and aligns returned reservation metadata with committed state.
demo_app/src/checkout/submit-order.ts Uses allSettled for concurrent runs and only escalates non-out-of-stock failures.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 20 to +24

const record = getInventoryRecord(sku);

if (record.available < quantity) {
throw new Error(`OutOfStock: ${sku}`);
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The out-of-stock guard after the delay fixes the TOCTOU behavior, but the nearby comment about an “Intentional bug” making the pre-check stale is now misleading (the stale pre-check no longer causes an incorrect commit). Consider updating/removing that comment and/or removing the earlier snapshot-based pre-check to avoid keeping a stale-check pattern in the example.

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +23
const hardFailure = settled.find(
(result) =>
result.status === "rejected" &&
!(result.reason instanceof Error && result.reason.message.startsWith("OutOfStock:"))
);
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filtering expected failures by checking error.message.startsWith("OutOfStock:") is brittle (message text is not a stable API) and makes it easy to accidentally treat a real error as ignorable after a message change. Prefer a typed error (e.g., class OutOfStockError extends Error) or an explicit error code/name check, ideally via a small helper like isOutOfStockError(reason).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants