Shopify Is Showing Off HTML-in-Canvas, While Developers Are Still Writing Long Posts About Lost Tokens
Tobi Lütke pointed everyone to Expo Mode, demoing it based on Google's new HTML-in-Canvas API. In the replies, a developer posted a long post: refresh tokens have a recovery mechanism, but when a cycle token is lost, all you can do is wait for the merchant to reauthorize.
Tobi Lütke posted just one sentence on X: go find Expo Mode. He said it was built with Google's new HTML-in-Canvas API, and Shopify may be among the first to use it. The original post is here.
The video poster uses a blue key visual. On the left side, written vertically, is Exponential, with a line of small text below: Everything new for non-linear growth. On the right is a node network, with labels such as Agentic, Sidekick, and Online connected by lines. In the lower left it says 400M+ shoppers with Shop Pay accounts*, and in the lower right it says Shopify Payments prevents 12K+ high-risk payments each minute.
This tweet doesn't carry much information. It's more of an entry point: what Expo Mode is, how to get in, and what exactly it can do—Tobi doesn't elaborate. Someone in the replies directly asks which button to press to enter Expo Mode. Kurt Elster left a comment: bug report, the Konami code doesn't respond on this page.
The truly informative part is another reply. Jon Purvis posted a long post from the Shopify developer community titled Please add recovery parity with refresh tokens. The post is about a migration failure involving offline access tokens and has nothing to do with Expo Mode. The post is here.
The background isn't complicated. Shopify is migrating non-expiring offline access tokens to expiring tokens plus refresh tokens. For backend apps, this token is the key to accessing the store. Shopify recently added a more robust recovery mechanism for refresh tokens: if a refresh succeeds but the app doesn't save the new token, the old refresh token can still be used one more time. The problem lies in cycle—that is, exchanging the old long-lived token for a new expiring token pair.
The failure chain Jon Purvis describes is: the app uses the old shpat_ as the subject token to initiate a cycle; Shopify accepts the exchange, destroys the old token in the same transaction, and sends back a new access token and refresh token. If the app then loses the HTTP response, or the worker crashes, or the database write fails, the new token is not saved and the old token is already gone. Retrying then returns invalid_subject_token. The store becomes an orphan, and all you can do is wait for the merchant to reopen the app and authorize it again.
Shopify's docs already state that cycling is irreversible and not suitable for replay. The docs even acknowledge that after an app loses the response, the store has no usable token, and the merchant must reauthorize. Jon Purvis's request is: refresh has a recovery path, so cycle should too. Either provide a bounded retry window, or make a second call with the same subject token idempotently return the same token pair, or give the Partner side a recovery API that doesn't require the merchant's browser.
This contrast is more interesting than the demo itself. The front end is showing where HTML-in-Canvas can take interfaces; the back end is discussing whether one lost response can turn an installation into a dead store. Agentic, Sidekick, webhooks, scheduled sync—these words all point to the same kind of app: the merchant isn't in the admin, but backend tasks still need to run. It is precisely these apps that most fear having to wait for the merchant to come back and click authorize after a cycle loses the response.
Expo Mode is worth a look. While looking, also scroll through the replies. The Konami code not responding is a joke. Token retries not responding is a support ticket.
发布时间: 2026-10-29 05:32