{"record":{"id":"4ff54aef3eaeb1c6","repo":"gatsbyjs/gatsby","slug":"response-statustext","errorCode":null,"errorMessage":"response.statusText","messagePattern":"response\\.statusText","errorType":"http","errorClass":"HttpError","httpStatus":null,"severity":"error","filePath":"packages/gatsby-source-shopify/src/clients.ts","lineNumber":38,"sourceCode":"      method: `POST`,\n      headers: {\n        \"Content-Type\": `application/json`,\n        \"X-Shopify-Access-Token\": options.password,\n      },\n      body: JSON.stringify({\n        query,\n        variables,\n      }),\n    })\n\n    if (!response.ok) {\n      const waitTime = 2 ** (retries + 1) + 500\n      if (response.status >= 500 && waitTime < MAX_BACKOFF_MILLISECONDS) {\n        await new Promise(resolve => setTimeout(resolve, waitTime))\n        return graphqlFetch(query, variables, retries + 1)\n      }\n\n      throw new HttpError(response)\n    }\n\n    const json = await response.json()\n    return json.data as T\n  }\n\n  return { request: graphqlFetch }\n}\n\nexport function createRestClient(options: IShopifyPluginOptions): IRestClient {\n  const baseUrl = `https://${options.storeUrl}/admin/api/${options.apiVersion}`\n\n  async function shopifyFetch(\n    path: string,\n    fetchOptions = {\n      headers: {\n        \"X-Shopify-Access-Token\": options.password,\n      },","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby-source-shopify/src/clients.ts#L20-L56","documentation":"Thrown by createGraphqlClient in gatsby-source-shopify when the Shopify Admin API responds with a non-ok status that is not retried (i.e. not a 5xx within the backoff window). The error message is response.statusText from node-fetch, and the full Response is attached as error.response for inspection. Common status codes: 401 (bad password/token), 403 (scope mismatch), 404 (wrong apiVersion/storeUrl), 429 (rate limit exceeded the backoff budget).","triggerScenarios":"Wrong Shopify storeUrl or apiVersion producing 404; invalid or revoked access token producing 401; app uninstalled mid-build producing 403; rate-limit 429 that exceeded the MAX_BACKOFF_MILLISECONDS window; Shopify API version deprecated and removed.","commonSituations":"Token expired or app was uninstalled; apiVersion string mistyped or pinned to an old version that Shopify removed; storeUrl includes https:// or trailing slash; password field set to the API key instead of the secret; CI using a stale env var.","solutions":["Inspect error.response.status and error.response.statusText to identify the failure class.","For 401/403: regenerate the Shopify Admin API access token and verify the app's access scopes include the queried resources.","For 404: confirm storeUrl (no protocol/scheme) and apiVersion (e.g. 2024-01) match a supported Shopify Admin API version.","For 429: reduce parallelism or wait for the rate-limit window to reset; the plugin only retries 5xx, so throttle upstream."],"exampleFix":"// before\nresolve: `gatsby-source-shopify`,\noptions: { storeUrl: `https://mystore.myshopify.com`, password: process.env.SHOPIFY_KEY }\n\n// after\nresolve: `gatsby-source-shopify`,\noptions: { storeUrl: `mystore.myshopify.com`, password: process.env.SHOPIFY_ADMIN_TOKEN, apiVersion: `2024-01` }","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"function isHttpError(e): e is Error & { response: import('node-fetch').Response } { return e instanceof Error && 'response' in e && typeof (e as any).response?.status === 'number' }","tryCatchPattern":"try { await client.request(query, variables) } catch (e) { if (isHttpError(e)) { if (e.response.status === 401) reporter.panic('Shopify token invalid/expired'); if (e.response.status === 404) reporter.panic('Shopify storeUrl or apiVersion wrong') } throw e }","preventionTips":["Store the Shopify Admin token in a secret manager and rotate it","Verify storeUrl has no protocol/scheme and apiVersion is current","Add a preflight GET to /admin/api/<version>/shop.json to validate credentials before sourcing","Monitor 429s and throttle upstream to stay under Shopify rate limits"],"tags":["shopify","http","auth","network"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}