TypeError: Cannot read properties of undefined (reading 'replace') - Trying to establish Rest Client

Topic summary

A developer encountered a TypeError: Cannot read properties of undefined (reading 'replace') when attempting to establish a Shopify REST client using the @shopify/shopify-api library.

Technical Context:

  • The error occurred when creating a new REST client with new shopify.clients.Rest()
  • The setup includes Express.js, Firebase Firestore for session storage, and ngrok for local development
  • The code implements OAuth authentication flow with session management

Code Structure:

  • Session data is stored/retrieved from Firestore
  • The /fetch endpoint attempts to reconstruct sessions and make API calls
  • Authentication callback saves session data to the database

Resolution:
The original poster resolved the issue independently but did not share the solution before the thread ended. The specific cause of the undefined property error remains undocumented in this discussion.

Summarized with AI on November 11. AI used: claude-sonnet-4-5-20250929.
import "@shopify/shopify-api/adapters/node";
import { shopifyApi, LATEST_API_VERSION, Session} from "@shopify/shopify-api";
import express from "express";
import dotenv from "dotenv";
import axios from "axios";
dotenv.config();

import cookieParser from 'cookie-parser';

import { initializeApp, applicationDefault, cert } from 'firebase-admin/app';
import { getFirestore, Timestamp, FieldValue, Filter } from 'firebase-admin/firestore';
import serviceAccount from './serviceKey.json' assert { type: 'json' };// const { initializeApp, cert } = require('firebase-admin/app');

initializeApp({
  credential: cert(serviceAccount)
});

const db = getFirestore();

const host = "sawfly-wealthy-mosquito.ngrok.app";
console.log(host);

const shopify = shopifyApi({
  apiKey: process.env.apiKey,
  apiSecretKey: process.env.apiSecretKey,
  scopes: ["read_orders", "write_orders", "read_products", "write_products"],
  hostName: host,
  apiVersion: LATEST_API_VERSION,
  
});

const app = express();

app.use(cookieParser());

const port = process.env.PORT || 3000;

app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
  console.log(`Ngrok host: https://${host}/`);
  console.log(`Ngrok auth host: https://${host}/auth?shop=${process.env.SHOPNAME}`);
  console.log(`Ngrok auth callback host:  https://${host}/auth/callback`);
  console.log(`Ngrok fetch some data host: https://${host}/fetch`);
});

/*
  when calling auth, you need the name of the user's store before you 
  can correctly request the website application

  You just ask the user to provide a domain that can be found when they go to:
  'https://admin.shopify.com/store/YOURSTORE' -> settings -> top left
  below username, copy and paste shopname

*/

app.get("/auth", async (req, res) => {
  res.cookie('shopName', req.query.shop);
  await shopify.auth.begin({
    shop: shopify.utils.sanitizeShop(req.query.shop, true),
    callbackPath: "/auth/saveInfoRedirect",
    isOnline: false,
    rawRequest: req,
    rawResponse: res,
  });
});

app.get('/auth/saveInfoRedirect', async (req, res) => {
  // The library will automatically set the appropriate HTTP headers
  const callback = await shopify.auth.callback({
    rawRequest: req,
    rawResponse: res,
  });

  res.cookie('shopName', callback.session.shop); //write this to local storage so it can be accessed from

  const data = {
    session: JSON.stringify(callback.session.toObject()),
  };
  const response = await db.collection('clients').doc(callback.session.shop).set(data);

  res.redirect('/fetch?shopName=' + callback.session.shop);
});

app.get('/fetch', async (req, res) => {
  //fetch the path from the url parameters

  const path = req.query.path;

  const fetchSession = await getSessionFromStorage(req.query.shopName);

  const session = new Session(fetchSession);

  console.log(session, "reconstructed session");

  if (!session) {
    res.status(401).send('Session not found, please reauthenticate ');
    res.redirect(`/auth?shop=${process.env.SHOPNAME}`);
  }

  try{
    console.log('establishing client...');
    const client = new shopify.clients.Rest({
      session,
      apiVersion: LATEST_API_VERSION,
    });

    const data = await client.get({
      path: path,
    });

    res.json(data);
  }
  catch (error) {

    console.error(error);
    res.status(500).send("somethings not right here")
    sleep(1000);
  }

});

const getSessionFromStorage = async (name) => {
  const doc = await db.collection('clients').doc(name).get();
  return JSON.parse(doc.data().session);
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

I have this code and when trying to make a Rest Client I get the error

TypeError: Cannot read properties of undefined (reading 'replace')
    at C:\Users\**\Documents\shopify-app-sync\node_modules\@shopify\admin-api-client\dist\rest\client.js:86:30

I don’t really understand what I’m doing wrong, it’s probably obvious, but thanks for any help!

Figured it out, can’t figure out how to delete, sorry, thanks for the consideration!