GraphQL Admin API 'Invalid API key or access token' in production but works in local

Hello

I’m creating an app with the remix framework.

When in run npm run dev everything works. I can make request to the GraphQL admin API. But in production, after running rpm run build and npm run start I have this error

[API] Invalid API key or access token (unrecognized login or wrong password)
If you report this error, please include this id: a31d8298-71a7-4889-9370-0323611be086
    at NewHttpClient.throwFailedRequest (/srv/shopify-app-prp/node_modules/@shopify/shopify-api/lib/clients/http_client/http_client.ts:260:15)
    at NewHttpClient.<anonymous> (/srv/shopify-app-prp/node_modules/@shopify/shopify-api/lib/clients/http_client/http_client.ts:294:12)
    at Generator.next (<anonymous>)
    at fulfilled (/srv/shopify-app-prp/node_modules/tslib/tslib.js:166:62)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)

after this request

{
    method: 'POST',
    path: '/admin/api/2023-07/graphql.json',
    type: 'application/graphql',
    data: 'query {\n      shop {\n        id\n      }\n    }',
    extraHeaders: {
        'X-Shopify-Access-Token': 'shpua_*************'
    }
}

The only difference when I test the app locally is that the access token starts with shpca instead of shpua in production.

I checked everything I could think about.

In the env config the SHOPIFY_API_KEY and SHOPIFY_API_SECRET are the same as Client ID and the Client secret in the App config “Overview” tab. The SHOPIFY_APP_URL is the same as all the urls sets in the “App Setup”->“URLs” section. The SCOPES variable of the env file contains the same values than the .toml I’m using in local.

I have no idea where it could come from.

Thanks for your heal

Hey @pjeannin

How are you setting/loading the env vars when you run in production?

In production it’s running with PM2, so I use the ecosystem.config.js file.

And I know the environment variables are correctly loaded because I printed them and it’s the right values.

So I don’t know where the error come from.

I also printed the session used to make the request.

Here is the code :

const { session } = await authenticate.admin(request);
  const client =  new apiShopify.clients.Graphql({session});
  console.log(session);
  const id = (await client.query({
    data: `query {
      shop {
        id
      }
    }`
  })).body.data.shop.id;

I here is the value of session in production:

{
    id: 'offline_powerling-store.myshopify.com',
    shop: 'powerling-store.myshopify.com',
    state: '376036643479648',
    isOnline: false,
    scope: 'write_products,write_translations,write_locales',
    accessToken: 'shpua_********'
}

And in local :

{
    id: 'offline_powerling-store.myshopify.com',
    shop: 'powerling-store.myshopify.com',
    state: '292064861688404',
    isOnline: false,
    scope: 'write_products,write_translations,write_locales',
    accessToken: 'shpca_******'
}

Curious that the access tokens are different. If you’re using the same app credentials, it could be generating a new token if you install on local/production. Difficult to tell without know more about your setup. What happens if you reinstall on production?

I tried to reinstall the app in production.

I now have this error :

TypeError: Cannot read properties of undefined (reading 'statusCode')
    at /srv/shopify-app-prp/node_modules/@shopify/shopify-api/adapters/node/adapter.ts:36:41
    at Generator.next (

Here is the full configuration of the app, you might need it :

module.exports = {
  apps : [{
    name   : "shopify-client-app-prp",
    cwd : "/srv/shopify-app-prp",
    script : "npm run start",
    env : {
        "BASE_URL" : "https://appify-prp.powerling-tp.com/api",
        "SHOPIFY_API_KEY" : "",
        "SHOPIFY_API_SECRET" : "",
        "SCOPES" : "read_products,read_locales,write_products,write_translations,write_locales,read_translations",
        "PORT" : 8010,
        "SHOPIFY_APP_URL" : "https://appify-connect-prp.powerling-tp.com"
    }
  }]
}

The BASE_URL env variable is for an other user in the app, it has nothing to do with the shopify config.

All the app is in the /srv/shopify-app-prp directory, and I run rpm run build before starting the app with pm2.

Here is the shopify.server.js. The ‘authenticate’ variable used to generate the session is exported in the file

import "@shopify/shopify-app-remix/adapters/node";
import '@shopify/shopify-api/adapters/node';
import {
  AppDistribution,
  DeliveryMethod,
  shopifyApp,
  LATEST_API_VERSION,
} from "@shopify/shopify-app-remix";
import { PrismaSessionStorage } from "@shopify/shopify-app-session-storage-prisma";
import { restResources } from "@shopify/shopify-api/rest/admin/2023-07";
import {shopifyApi, LATEST_API_VERSION as API_VERSION} from '@shopify/shopify-api';
import prisma from "./db.server";

export const apiShopify = shopifyApi({
  apiKey: process.env.SHOPIFY_API_KEY,
  apiSecretKey: process.env.SHOPIFY_API_SECRET || "",
  scopes: process.env.SCOPES?.split(","),
  apiVersion: API_VERSION,
  hostName: process.env.HOST_NAME?.replace(/https?:\/\//, "") || "myshopify.com",
  isEmbeddedApp: true,
})

const shopifyApplication = shopifyApp({
  apiKey: process.env.SHOPIFY_API_KEY,
  apiSecretKey: process.env.SHOPIFY_API_SECRET || "",
  apiVersion: LATEST_API_VERSION,
  scopes: process.env.SCOPES?.split(","),
  appUrl: process.env.SHOPIFY_APP_URL || "",
  authPathPrefix: "/auth",
  sessionStorage: new PrismaSessionStorage(prisma),
  distribution: AppDistribution.AppStore,
  restResources,
  webhooks: {
    APP_UNINSTALLED: {
      deliveryMethod: DeliveryMethod.Http,
      callbackUrl: "/webhooks",
    },
  },
  hooks: {
    afterAuth: async ({ session }) => {
      shopifyApplication.registerWebhooks({ session });
    },
  },
  ...(process.env.SHOP_CUSTOM_DOMAIN
    ? { customShopDomains: [process.env.SHOP_CUSTOM_DOMAIN] }
    : {}),
});

export default shopifyApplication;
export const apiVersion = "2023-07";
export const addDocumentResponseHeaders = shopifyApplication.addDocumentResponseHeaders;
export const authenticate = shopifyApplication.authenticate;
export const login = shopifyApplication.login;
export const registerWebhooks = shopifyApplication.registerWebhooks;
export const sessionStorage = shopifyApplication.sessionStorage;

Hey @pjeannin

Consider configuring multiple environments like this. This will avoid the token issues your seeing / generate tokens for each store:environment.

Are you able to share the code (without any sensitive data, via DM is fine) so I can take a look at the statuscode issue?

I’m having this same statusCode issue during app install. This is new for me, haven’t had this problem in the last year until a few weeks ago. This issue also has discussed this problem with no response yet from Shopify.

https://github.com/Shopify/shopify-app-js/issues/484

I can send my code or whatever is helpful. But help would most certainly be appreciated!

this is happening during the first part of the oAuth process in my ‘/begin’ endpoint where I am running shopify.auth.begin. Note this has been working fine for about a year and just started happening recently.

TypeError: Cannot read properties of undefined (reading ‘statusCode’)
at /var/task/apps/app/.next/server/app/api/shopify/uninstall/route.js:1:4687
at Generator.next ()
at /var/task/apps/app/.next/server/chunks/849.js:1:14094
at new Promise ()
at Module.h (/var/task/apps/app/.next/server/chunks/849.js:1:13843)
at t.nodeConvertIncomingResponse (/var/task/apps/app/.next/server/app/api/shopify/uninstall/route.js:1:4614)
at /var/task/apps/app/.next/server/chunks/3366.js:1:12042
at Generator.next ()
at s (/var/task/apps/app/.next/server/chunks/849.js:1:13899)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Also facing this issue out of nowhere. And I have only ever worked in the dev environment (very new project).

I thought it had to do with my scopes at first. But it did not.

Now even when I stash all my changes the issue persists?

Hey @felixmpaulus

The statusCode issue? Are you seeing this with a freshly generated app / can you (or @jjrise ) provide replication steps please?

The issue that throws ‘[API] Invalid API key or access token (unrecognized login or wrong password)’.

Unfortunately I have no idea how to reproduce it.

It came out of nowhere.

Restarting the server did not help.

Stashing all changes did not help (and I know it worked on the previous commit).

And it went await out of nowhere. Just started working again…

I suspect it is a cloudfront issue? Sorry that I can’t be of any more help.

No probs. Thanks for the info. Please let me know if you see it again.

Good evening Scott,

This is still happening to me daily still. Can I DM you code examples?

Hey @jjrise - please do :slightly_smiling_face: