Write_discounts access scope disappeared from many of our merchants

We’ve had several hundred of our merchants randomly lose one of our required scopes (write_discounts) within the last week or so.

We use Shopify managed installs and have the write_discounts scope as a required scope in our TOML:

[access_scopes]
# Learn more at https://shopify.dev/docs/apps/tools/cli/configuration#access_scopes
scopes = "read_products,write_discounts,write_price_rules"
optional_scopes = ["read_customers"]
use_legacy_install_flow = false

We’ve been using managed installs for about a year now, with these scopes unchanged since migrating to that. But in the last week we had two merchants come in because the discount writing functionality in our app was not working anymore for them and we were getting errors on our backend saying they didn’t have the correct scope for those GraphQL APIs. They were using the functionality as recently as last week, so they did have the scopes then.

We looked at any other merchants who have logged in to our app for the last 6 months and we have about 250 other merchants in the same boat where they are just missing that specific scope. Theoretically, they shouldn’t have been able to even get into our app without approving.

So far, the only way we’ve been able to resolve the issue is to have the merchants uninstall and reinstall. Logging into the app isn’t sufficient to getting Shopify to kick off the approval of scopes. Since the managed installs control that process entirely, there seems to be two bugs:

  1. Why did these require scopes randomly go away for some of our merchants? (It was also only the write_discounts scope every time… the others were fine)
  2. Why isn’t logging into the app for these merchants asking them to reapprove the required scope if they don’t have it?

I didn’t want to share any customer specific details, but if any Shopifolk want to reach out to me for those details, I can happily share them if that’s helpful into looking into it.

Hey @marcbaumbach, thanks for reporting this.

I’ll take a look and see what I can find. Can you share when you noticed this happening (so I have more of a timeline). Have you made any other changes to your app configuration around the same time?

Can you test if adding read_discounts alongside write changes anything?

Can you also share an x-request-id from one of the API requests that returns an error related to this missing scope?

Hey @KyleG-Shopify, thanks for looking into it.

Unfortunately, none of our test shops hit this issue, only merchants’ shops. Since we didn’t want to block the ones that came into our support from utilizing our app’s functionality, we assisted the customers who have reached out by asking them to uninstall/reinstall in order to restore functionality.

If we had our own accounts experiencing this, I would certainly quickly test out the read_discounts scope, but I’d rather not confuse our existing customers by having them approve a different scope. Are you saying to add the read_discounts in addition to the write_discounts? I know typically the write_discounts gets you the read by default.

The requests that are failing are all, rightfully, failing since we are missing that scope, but they shouldn’t have been able to get into our app to start those operations without going through the managed scope process. So I don’t suspect they would be useful as they fail if you run the operations right now too.

In terms of timeline, we noticed two of our merchants came in within the last 2 weeks, so it feels more recent. But if I look at common times that a lot of our merchants have received updates to their accounts, I see a common thread of “2025-10-23 17:37:48” in UTC (About 80 of the mentioned accounts were modified around that time). Unfortunately we don’t have logs going back that far.

I’m happy to share specific merchants with you in private comms if that’s helpful. I can give login dates/times too which should have triggered them to get the scope too. I can see it happened again today for one merchant.

One other interesting piece of data is that all of these merchants have been with us since before we introduced this scope on October 2, 2024. We switched to managed installs on May 15, 2025 and 250+ merchants have logged in since that May date. So curiously it seems to be only affecting merchants that installed before we originally had this scope, but they should have all got it through the managed install. It’s the only scope affected by this though, all other required scopes are fine.

Sorry I don’t have much more info, we just don’t have much on our side as to when/why the scope disappeared.

I just had a thought and I don’t think we’ve actually seen this behavior in the past, but can you confirm whether a new offline access token must be requested after a managed install approves new scopes? Does the old offline (non-expiring) access token inherit those new scopes? It seems to work for optional scopes, but that’s the only way I could imagine the offline tokens not having access to the new scope.

If that’s the case, is the suggestion to check the active scopes from the session token and make sure they match the offline token on login and if they don’t match we go grab a new offline token with the session/online token?

And finally if we are supposed to do it that way, do the newly minted offline token remain the same as the old token and it just gets the refreshed scopes under the covers or do you get a new token value? If you get a new token value, does the old one stop working immediately or ever? Just trying to think through situations where there’s a lot of inflight processes using a possibly stale token.

Hey @marcbaumbach, you bring up a really good point around the offline access tokens.

Since uninstalling and reinstalling is working (which would require a new access token on your end) it does seem that the access token you’re using currently doesn’t have those scopes attributed.

I’ll look in to this today and report back to you.