Storefront customerAddressUpdate modifies address id

Topic summary

The Storefront API’s customerAddressUpdate mutation returns a different address ID with each request, even when updating the same address successfully. The original ID remains functional for future mutations, but the changing returned ID complicates caching strategies.

Root Cause:
The returned ID is a Base64-encoded string containing:

  • The actual mailing address ID (which stays constant)
  • A model_name query parameter
  • The customer_access_token used in the request

Since the access token portion changes between requests, the full encoded ID appears different each time.

Workarounds:

  • Decode the Base64 response to extract the stable address ID
  • Use middleware to handle the decoding automatically
  • For Apollo cache management: create a custom adminId field that parses the stable ID from the encoded string and set it as the cache key
  • Format the ID as gid://shopify/MailingAddress/{address.id}?model_name=CustomerAddress when making requests

One user reported receiving an “Invalid global ID” error when using the gid:// format, seeking additional guidance.

Summarized with AI on November 19. AI used: claude-sonnet-4-5-20250929.

I’m trying to allow a customer to update their address through the Storefront API. The mutation works as expected but the returned id is different than the provided id. I’m able to continue referencing the address by its original id and make future mutations however the returned id changes every time. Running the exact same mutation multiple times returns different ids each time which makes me think it’s possibly a hash of the data (with the updated_at field changing). This presents some difficulties in caching as there isn’t a good way to update the cache by referencing the address id from the returned result.

Any insight into why ids are changing would be much appreciated.

This is the mutation:

mutation customerAddressUpdate(
    $customerAccessToken: String!
    $id: ID!
    $address: MailingAddressInput!
  ) {
    updateCustomerAddress: customerAddressUpdate(
      customerAccessToken: $customerAccessToken
      id: $id
      address: $address
    ) {
      customerAddress {
        id
      }
    }
  } 

So I did some digging on this one. While the ID is changing from request to request, it’s not a new object being created each time. Take this ID:

Z2lkOi8vc2hvcGlmeS9NYWlsaW5nQWRkcmVzcy82ODA1NTE0NDUzP21vZGVsX25hbWU9Q3VzdG9tZXJBZGRyZXNzJmN1c3RvbWVyX2FjY2Vzc190b2tlbj14TDNJVmlzenBCdHNtZlNfcWxPUHIzZE14NHh5QUNZVTVwNUxuRUhibEFZQ29zbFVPcGdacWhQOEJDSnYyVnZtLXpYeDNneHR4WjVDRnd4bWhOZHRwbmlqenFUVkgzOWFwM0U5ZmV5aHhPeElxLVRPVFdFUDIyRWR4Q3NZb2FwaHE4NGtHY28tRVJiMHc3VWxCMjRPaFl2YXEwM05xYkgtdlJBYWREdnp0Y25peVlCZkxJOGZkOTB0ZkhXQXZ3X0tNRW13YzVjYTNOdlYwa0lJSzJOSlZwVFc3T2JnSnNWNTN5cTY3SnZlal9rdTg1Q1lack1reW9Pel91akpxSXRn

When I decode the Base64 string representation, it comes out like this:

gid://shopify/MailingAddress/6805514453?model_name=CustomerAddress&customer_access_token=xL3IViszpBtsmfS_qlOPr3dMx4xyACYU5p5LnEHblAYCoslUOpgZqhP8BCJv2Vvm-zXx3gxtxZ5CFwxmhNdtpnijzqTVH39ap3E9feyhxOxIq-TOTWEP22EdxCsYoaphq84kGco-ERb0w7UlB24OhYvaq03NqbH-vRAadDvztcniyYBfLI8fd90tfHWAvw_KMEmwc5ca3NvV0kIIK2NJVpTW7ObgJsV53yq67Jvej_ku85CYZrMkyoOz_ujJqItg

You’ll see that the mailing address ID itself remains the same, and so does the model_name “query parameter”. It’s the customer_access_token parameter that appears to change from time to time, and it never seems to match the customer access token I used to make the mutation. I don’t know exactly what that is, but it’s possibly some kind of encoded representation of the access token, and that’s the reason why the ID is changing from request to request.

Does that help a bit?

Cheers.

Thanks Alex! That does help a lot. I got around the issue I was having with some middleware but decoding the response and pulling out the id would’ve worked as well.

Hi! I’m struggling with the same issue here.

I’m trying to update a customer’s address with the Storefront API, but the GraphQL mutation returns a “Invalid global ID” error when using the “gid://“ ID. Can you please help me?

Thanks!

I also ran into the same issue. In my case I’m using Apollo to manage the cache and I noticed that when an address was modified, a new address object would be added to the cache with a different id and the list of customer addresses would not be updated.

To solve I created a local field adminId on the MailingAddress object, which parses out the mailing address id from the base 64 encoded global id. I then set adminId to be the cache key.

export const cache = new InMemoryCache({
  typePolicies: {
    MailingAddress: {
      fields: {
        adminId: {
          read(_, { readField }) {
            const gid = atob(readField('id'));
            const adminId = gid.substring(
              gid.lastIndexOf('/') + 1,
              gid.indexOf('?')
            );
            return adminId;
          }
        }
      },
      keyFields: ['adminId']
    }
  }
});

use the id as global id:

gid://shopify/MailingAddress/${address.id}?model_name=CustomerAddress