Fix 401 Unauthorized on cart AJAX endpoints during shopify theme dev
#6839
+135
−3
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.


WHY are these changes introduced?
Closes https://github.com/Shopify/developer-tools-team/issues/1034.
Cart AJAX endpoints (
/cart/add.js,/cart/update.js,/cart/change.js,/cart.js,/cart.json) return 401 Unauthorized when runningshopify theme devon CLI 3.89.0, but work correctly on 3.88.0. 5+ developers affected with confirmed reproduction.WHAT is this pull request doing?
Conditionally omits the
Authorization: Bearer <storefrontToken>header on proxied requests to endpoints that use session-cookie auth (cart, checkout, account). CDN/asset paths continue receiving the Bearer token for theme preview rendering.Changes:
proxy.tsCART_SESSION_PATTERNconstant,needsBearerToken()helper, updated Authorization conditionalproxy.test.ts.changeset/fix-cart-ajax-401.md@shopify/themeKey design decisions:
Denylist over allowlist: The set of cookie-auth endpoints is small and stable (cart, checkout, account). The set of Bearer-needing endpoints is large and open-ended (CDN assets, vanity CDN rewrites,
.js.liquidfiles, etc.). An allowlist would risk silent rendering failures; a denylist's failure mode is a loud 401 — easy to detect.Separate
CART_SESSION_PATTERNfromCART_PATTERN:CART_PATTERN(/^\/cart\//) is for routing — it deliberately excludesGET /cart(the cart HTML page, which should render locally).CART_SESSION_PATTERN(/^\/cart(\/|\.js|\.json|$)/) is for auth — broader because ALL cart paths use session-cookie auth. Collapsing these would contaminate routing with auth concerns.Reuse
CHECKOUT_PATTERNandACCOUNT_PATTERN: Their routing and auth scopes currently align. The comment inneedsBearerToken()warns future editors that changes to those patterns should consider auth implications.Query string stripping:
needsBearerToken()strips query strings before regex matching to ensureACCOUNT_PATTERN's$anchor matches correctly (e.g.,/account?foo=bar).How to test your changes?
Automated:
Manual (end-to-end):
Note: I'm currently having 1Password issues so I'm locked out of the admin and haven't been able to manually test these myself
shopify theme devon a test storeMeasuring impact
How do we know this change was effective? Please choose one:
Checklist