All app users oauth tokens went "invalid" at the same time (saying ACCESS_DENIED when using)- SOLVED

Shopify Partner
17 0 6



 We have a (live) app, and when people add it to their store, it hits our site's callback url, and then we use the passed-in code to request the oauth access token, which we then save in our DB.


 We use this token for a few different follow-up requests (basically just to get store info, some revenue numbers, and a list of the store's orders and individual order details). We have added permissions 'read_order' and 'read_all_orders' for this.


The queries were al working fine and returning data, up until last night, when all of the sudden the job requests started giving ACCESS_DENIED without any explanation. The Shopify app and store wasn't changed, and I've tested this on 4 accounts so far with the same result.


The error goes away if I re-associate the app, but we are trying to avoid forcing users to have to do that. It also doesn't seem logical in this situation.


The docs suggest this oauth token is "permanent", but can anyone possibly clarify?

I'd like to know:


1) Why the ACCESS_DENIED error is occurring, for all users all of the sudden, and goes away after re-associating the app per user, even though the docs suggest it's a one-time thing? Is it possible that all access tokens associated to the app, across all users, can be invalidated like this, for some reason?


2) Is there a way to avoid this situation in the future, so we don't have to come up with a solution for users to re-authorize the app through the Shopify dashboard? Is there some other way to refresh or generate the access token without further user-intervention after the first time?


My only intuition is that maybe our app got flagged while I was testing two or three different accounts, and making maybe 5-10 API calls (Rest and GraphQL) every minute or two... though one would think that would be fine...


One of the test stores I'm working with is (among others).


For further clarification, we are following the docs:


and doing this in code:




// Get the code and shop from the Shopify callback request:
const { code, shop } = body;

// Ask for a permanent access token using the code:
const { data: { access_token, scope } } = await`https://${shop}/admin/oauth/access_token`, {
    client_id: process.env.SHOPIFY_APP_ID,
    client_secret: process.env.SHOPIFY_APP_SECRET,

// ...we then save that token to the DB, and use it in these calls:

private getBaseUrl = (shop: string) => `https://${shop}/admin/api/${this.apiVersion}/graphql.json`;

private createApiInstance = (shop: string, token: string) => {
    return axios.create({
        baseURL: this.getBaseUrl(shop),
        headers: {
            'Content-Type': 'application/graphql',
            'X-Shopify-Access-Token': token





Which is returning the following failed job response (for all accounts/shops/tokens):




currentBulkOperation: {
  id: 'gid://shopify/BulkOperation/1151629918458',
  status: 'FAILED', 
  errorCode: 'ACCESS_DENIED',
  createdAt: '2022-03-29T19:04:29Z',
  completedAt: null,
  objectCount: '0',
  fileSize: null,
  url: null,
  partialDataUrl: null





They are fixed when we re-associate the app through Shopify, and it generates a new token, but we are trying to avoid forcing all users to have to do this after the first time.





UPDATE: Solved... it was because I added variant { id } to the orders query. Who would have thought adding a field to the orders query would require other permissions besides read_orders/read_all_orders... Ah well, learned!

Replies 0 (0)