{"record":{"id":"e19cd8bb973f5fda","repo":"ChatGPTNextWeb/NextChat","slug":"network-response-was-not-ok","errorCode":null,"errorMessage":"Network response was not ok","messagePattern":"Network response was not ok","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"app/utils/ms_edge_tts.ts","lineNumber":263,"sourceCode":"  }\n\n  /**\n   * Fetch the list of voices available in Microsoft Edge.\n   * These, however, are not all. The complete list of voices supported by this module [can be found here](https://docs.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support) (neural, standard, and preview).\n   */\n  // getVoices(): Promise<Voice[]> {\n  //   return new Promise((resolve, reject) => {\n  //     axios\n  //       .get(MsEdgeTTS.VOICES_URL)\n  //       .then((res) => resolve(res.data))\n  //       .catch(reject);\n  //   });\n  // }\n  getVoices(): Promise<Voice[]> {\n    return fetch(MsEdgeTTS.VOICES_URL)\n      .then((response) => {\n        if (!response.ok) {\n          throw new Error(\"Network response was not ok\");\n        }\n        return response.json();\n      })\n      .then((data) => data as Voice[])\n      .catch((error) => {\n        throw error;\n      });\n  }\n\n  /**\n   * Sets the required information for the speech to be synthesised and inits a new WebSocket connection.\n   * Must be called at least once before text can be synthesised.\n   * Saved in this instance. Can be called at any time times to update the metadata.\n   *\n   * @param voiceName a string with any `ShortName`. A list of all available neural voices can be found [here](https://docs.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support#neural-voices). However, it is not limited to neural voices: standard voices can also be used. A list of standard voices can be found [here](https://docs.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support#standard-voices)\n   * @param outputFormat any {@link OUTPUT_FORMAT}\n   * @param voiceLocale (optional) any voice locale that is supported by the voice. See the list of all voices for compatibility. If not provided, the locale will be inferred from the `voiceName`\n   */","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/ChatGPTNextWeb/NextChat/blob/defdcdb55d850cd12c4c657eb83729fd66e215c0/app/utils/ms_edge_tts.ts#L245-L281","documentation":"Thrown at app/utils/ms_edge_tts.ts:263 inside MsEdgeTTS.getVoices() when fetch(MsEdgeTTS.VOICES_URL) resolves with response.ok === false. The VOICES_URL is the public Microsoft Edge 'readaloud' voices list endpoint (speech.platform.bing.com/.../voices/list?trustedclienttoken=...). Any non-2xx HTTP status from that endpoint triggers the generic 'Network response was not ok'.","triggerScenarios":"Microsoft's endpoint returns 4xx/5xx (transient outage, deprecated token, geo-block); a captive portal / proxy returns a non-2xx intercept page; the request is made from a context where the endpoint is unreachable but fetch still resolves (e.g. corporate firewall returning 403); DNS/SSL issue surfaces as a non-ok response via a proxy layer.","commonSituations":"Running in a region where the Bing speech endpoint is geo-restricted; the trustedclienttoken changes upstream and the old URL 404s; offline/air-gapped environment; browser CORS preflight rejected with a non-2xx; running behind a transparent proxy that blocks bing.com.","solutions":["Check connectivity to https://speech.platform.bing.com from the host and confirm the trustedclienttoken in VOICES_URL is still current.","Wrap getVoices() in a retry with exponential backoff for transient 5xx responses.","Cache the last successful voice list locally so a later fetch failure can fall back instead of throwing.","Surface the actual HTTP status code in the error so the cause (geo-block vs outage vs token) is diagnosable."],"exampleFix":"// before\nif (!response.ok) {\n  throw new Error(\"Network response was not ok\");\n}\n\n// after\nif (!response.ok) {\n  throw new Error(\n    `Edge TTS voices endpoint returned ${response.status} ${response.statusText}`,\n  );\n}","handlingStrategy":"retry","validationCode":"async function voicesEndpointReachable(): Promise<boolean> {\n  try {\n    const res = await fetch(MsEdgeTTS.VOICES_URL, { method: \"HEAD\" });\n    return res.ok;\n  } catch {\n    return false;\n  }\n}\n\nif (!(await voicesEndpointReachable())) {\n  throw new Error(\"Edge TTS voices endpoint unreachable\");\n}","typeGuard":"function isOkResponse(res: Response): res is Response & { ok: true } {\n  return res.ok;\n}","tryCatchPattern":"async function getVoicesWithRetry(retries = 3): Promise<Voice[]> {\n  for (let attempt = 0; attempt <= retries; attempt++) {\n    try {\n      return await tts.getVoices();\n    } catch (e) {\n      if (attempt === retries) throw e;\n      await new Promise((r) => setTimeout(r, 2 ** attempt * 500));\n    }\n  }\n  throw new Error(\"unreachable\");\n}","preventionTips":["Cache the voice list after the first successful fetch so later failures degrade gracefully.","Verify the trustedclienttoken in VOICES_URL is still valid against the current Microsoft endpoint.","Confirm outbound access to speech.platform.bing.com from the deployment host."],"tags":["edge-tts","network","microsoft","http-status","third-party-api"],"backgroundTag":null,"analyzedSha":"defdcdb55d850cd12c4c657eb83729fd66e215c0","analyzedAt":"2026-08-12T09:57:26.489Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}