Do not have valid credential to use Customer Account API in Login route

ERROR Error: [h2:error:customerAccount] You do not have the valid credential to use Customer Account API.
Run `h2 env pull` to link your store credentials.
  `,{data:A}=await L(C),S=A?.storefrontCustomerAccessTokenCreate?.customerAccessToken;S&&xe({customerAccessToken:S});}return {login:async C=>{h();let A=new URL(m("AUTH")),S=Sr(),w=$e();if(A.searchParams.set("client_id",t),A.searchParams.set("scope","openid email"),A.searchParams.append("response_type","code"),A.searchParams.append("redirect_uri",y),A.searchParams.set("scope",m("LOGIN_SCOPE")),A.searchParams.append("state",S),A.searchParams.append("nonce",w),C?.uiLocales){let[U,V]=C.uiLocales.split("-"),F=U.toLowerCase();V&&(F+=`-${V.toUpperCase()}`),A.searchParams.append("ui_locales",F);}let q=Cr(),H=await Ar(q);return e.set(_,{...e.get(_),codeVerifier:q,state:S,nonce:w,redirectPath:Ve(s.url)||W(s,"Referer")||Er}),A.searchParams.append("code_challenge",H),A.searchParams.append("code_challenge_method","S256"),Ee(A.toString())},logout:async C=>{h();let A=e.get(_)?.idToken,S=mt({requestUrl:p,defaultUrl:p,redirectUrl:C?.postLogoutRedirectUri}),w=A?new URL(`${m("LOGOUT")}?${new URLSearchParams([["id_token_hint",A],["post_logout_redirect_uri",S]]).toString()}`).toString():S;return ye(e),Ee(w,{headers:C?.headers||{}})},isLoggedIn:N,handleAuthStatus:b,getAccessToken:G,getApiUrl:()=>g,mutate:L,query:Xe,authorize:async()=>{h();let C=f.searchParams.get("code"),A=f.searchParams.get("state");if(!C||!A)throw ye(e),new M("Unauthorized","No code or state parameter found in the redirect URL.");if(e.get(_)?.state!==A)throw ye(e),new M("Unauthorized","The session state does not match the state parameter. Make sure that the session is configured correctly and passed to `createCustomerAccountClient`.");let S=t,w=new URLSearchParams;w.append("grant_type","authorization_code"),w.append("client_id",S),w.append("redirect_uri",y),w.append("code",C);let q=e.get(_)?.codeVerifier;if(!q)throw new M("Unauthorized","No code verifier found in the session. Make sure that the session is configured correctly and passed to `createCustomerAccountClient`.");w.append("code_verifier",q);let H={"content-type":"application/x-www-form-urlencoded","User-Agent":de,Origin:p},U=$?.();new Date().getTime();let F=m("TOKEN_EXCHANGE"),O=await fetch(F,{method:"POST",headers:H,body:w});if(!O.ok)throw new Response(await O.text(),{status:O.status,headers:{"Content-Type":"text/html; charset=utf-8"}});let{access_token:x,expires_in:B,id_token:he,refresh_token:Ze}=await O.json(),Qt=e.get(_)?.nonce,Wt=await Tr(he);if(Qt!==Wt)throw new M("Unauthorized",`Returned nonce does not match: ${Qt} !== ${Wt}`);let jt=x;o||(jt=await Tt(x,t,m("TOKEN_EXCHANGE"),p,{waitUntil:a,stackInfo:U,...X(s)}));let lo=e.get(_)?.redirectPath;return e.set(_,{accessToken:jt,expiresAt:new Date(new Date().getTime()+(B-120)*1e3).getTime()+"",refreshToken:Ze,idToken:he}),await J(),Ee(lo||Er)},UNSTABLE_setBuyer:xe,UNSTABLE_getBuyer:re}}function sn(e,t){return function(){try{if(!t)throw Error();new URL(e("CA_BASE_URL")),new URL(e("CA_BASE_AUTH_URL"));}catch{console.error(new Error("[h2:error:customerAccount] You do not have the valid credential to use Customer Account API.\nRun `h2 env pull` to link your store credentials."));let o="Internal Server Error";throw new Response(o,{status:500})}}}var cn="https://raw.githubusercontent.com/Shopify/hydrogen/main/docs/changelog.json";async function un({request:e,changelogUrl:t}){new URL(e.url).searchParams;return fetch(t||cn)}var Rr="cartFormInput";function z({children:e,action:t,inputs:r,route:o,fetcherKey:n}){let s=useFetcher({key:n});return jsxs(s.Form,{action:o||"",method:"post",children:[(t||r)&&jsx("input",{type:"hidden",name:Rr,value:JSON.stringify({action:t,inputs:r})}),typeof e=="function"?e(s):e]})}z.INPUT_NAME=Rr;z.ACTIONS={AttributesUpdateInput:"AttributesUpdateInput",BuyerIdentityUpdate:"BuyerIdentityUpdate",Create:"Create",DiscountCodesUpdate:"DiscountCodesUpdate",GiftCardCodesUpdate:"GiftCardCodesUpdate",LinesAdd:"LinesAdd",LinesRemove:"LinesRemove",LinesUpdate:"LinesUpdate",NoteUpdate:"NoteUpdate",SelectedDeliveryOptionsUpdate:"SelectedDeliveryOptionsUpdate",MetafieldsSet:"MetafieldsSet",MetafieldDelete:"MetafieldDelete"};function dn(e){let t={};for(let a of e.entries()){let u=a[0],i=e.getAll(u);t[u]=i.length>1?i:a[1];}let{cartFormInput:r,...o}=t,{action:n,inputs:s}=r?JSON.parse(String(r)):{};return {action:n,inputs:{...s,...o}}}z.getFormInput=dn;var T=`#graphql
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 ^
    at h (../../node_modules/@shopify/hydrogen/dist/production/index.js:299:2932)
    at (../../node_modules/@shopify/hydrogen/dist/production/index.js:299:145)
    at loader (../../app/routes/discount.$code.tsx:15:21)
    at callRouteLoader (../../node_modules/@remix-run/server-runtime/dist/esm/data.js:55:22)
    at handler (../../node_modules/@remix-run/server-runtime/dist/esm/routes.js:50:34)
    at actualHandler (../../node_modules/@remix-run/router/dist/router.js:4196:14)
    at (../../node_modules/@remix-run/router/dist/router.js:4204:89)
    at runHandler (../../node_modules/@remix-run/router/dist/router.js:4215:1)
    at callLoaderOrAction (../../node_modules/@remix-run/router/dist/router.js:4269:22)
    at (../../node_modules/@remix-run/router/dist/router.js:4150:27)

For some context:

  • This store is hosted on Oxygen through Hydrogen Sales Channel
  • We are getting this error in production and preview environments
  • The version of the packages are
    "@shopify/admin-api-client": "^1.0.0",
    "@shopify/hydrogen": "^2024.10.0",
    "@shopify/remix-oxygen": "^2.0.9",
    "@shopify/shopify-api": "^11.1.0",
    "@shopify/shopify-app-remix": "^3.1.0",

For the code on the login route:

import type {LoaderFunctionArgs} from '@shopify/remix-oxygen';

export async function loader({request, context}: LoaderFunctionArgs) {
  return context.customerAccount.login();
}

Is there any idea on how to resolve this? The Storefront API Token is readonly on the Hydrogen Sales Channel, so we are not able to modify it/update it

Do you have a PUBLIC_CUSTOMER_ACCOUNT_ID in your .env file?

Is it not PUBLIC_CUSTOMER_ACCOUNT_API_CLIENT_ID?
That’s the closest environment variable name I can find to what you have mentioned.
If missing it is an issue, would this be a problem of the Hydrogen Sales Channel? Or is there some way to generate it?

Ya sorry it is the PUBLIC_CUSTOMER_ACCOUNT_API_CLIENT_ID

You can grab it via h2 env pull, it should be in a .env file in your codebase.

Hmm, but this environment variable is set automatically by the Hydrogen Sales Channel and is stored as read-only, we tried h2 env pull, but that didn’t solve it.
And isn’t h2 env pull more for localhost development? Our problem is happening on production and the preview where the Hydrogen Sales Channel is managing the hosting.

Does it work locally?

Not working locally for me also, let me check with my rest of my team real quick also. But last I checked, they also do not know what to do regarding this issue

Do you mind telling me what your store is?

The store is https://reganharney.com

Let’s try to diagnose the local dev first since we can see the env variables there. You don’t have to reveal them all but what is the first few characters of PUBLIC_CUSTOMER_ACCOUNT_API_CLIENT_ID

The first few characters are
647dd352

Have you made any customizations to how the .env is read, I’m assuming not but have to ask. I just tried this myself on the version you specified and I haven’t been able to reproduce your problem.

Not that I know of. Most of the environment variables are passed in by the context parameter of the loader. We are simply just working with the quick start template provided by the Hydrogen framework.

Gotcha, is this an existing hydrogen storefront project or a fresh one?

The reason I’m asking is, maybe one way to check if something is wrong with the code is to spin up a fresh hydrogen storefront template and see if the login works there.

I will need to check with my team whether we have done this, I was also thinking about that :upside_down_face:. But currently, it’s night time over where I am, so I am not able to provide you an answer swiftly, but I will try on my own first and I try to get back to you quickly.

1 Like

this hydrogen storefront project is an existing one, created in August 2024

1 Like

Ok, it seems we figured out the solution. Turns out it was a missing environment variable in the env.d.ts, just needed to add the SHOP_ID variable to it and update the old environment variable to the new one in the server.ts

Thank you so much @Shawn_Lee-Kwong for your help

1 Like