koodo-reader/koodo-reader · error · Error

HTTP ${response.status}: ${response.body.substring(0, 200)}

Error message

HTTP ${response.status}: ${response.body.substring(0, 200)}

What it means

The AI connectivity test in AISetting sends a tiny chat completion ("Reply with OK.", max_tokens 10) via aiRequest and throws `HTTP <status>: <first 200 chars of body>` when it fails. Including the response body snippet surfaces provider-specific errors like 'invalid_api_key' or 'model_not_found' directly in the thrown message.

Source

Thrown at src/containers/settings/aiSetting/component.tsx:206

        ? endpoint + "chat/completions"
        : endpoint + "/chat/completions";
      const response = await aiRequest(
        chatEndpoint,
        "POST",
        {
          "Content-Type": "application/json",
          Authorization: `Bearer ${apiKey}`,
        },
        JSON.stringify({
          model: modelId,
          messages: [
            { role: "user", content: "Hi, just testing. Reply with OK." },
          ],
          max_tokens: 10,
        })
      );
      if (!response.ok) {
        throw new Error(
          `HTTP ${response.status}: ${response.body.substring(0, 200)}`
        );
      }
      const data = JSON.parse(response.body);
      const reply =
        data.choices?.[0]?.message?.content ||
        JSON.stringify(data).substring(0, 100);
      this.setState({ testResult: "success" });
      toast.success(this.props.t("Test successful") + ": " + reply);
    } catch (e: any) {
      this.setState({ testResult: "fail" });
      toast.error(this.props.t("Test failed") + ": " + e.message);
    } finally {
      this.setState({ isTesting: false });
    }
  };

  handleSave = async () => {

View on GitHub (pinned to 7d40df41e0)

Solutions

  1. Read the body snippet in the error message — it usually names the exact problem (invalid_api_key, model_not_found, insufficient_quota).
  2. 401/403: re-enter the API key and confirm it is active with billing/quota set up.
  3. 404 or model error: pick a model the key can access; verify the chat completions endpoint path.
  4. 429: check quota/usage on the provider dashboard or wait for the rate-limit window.
  5. Verify network reachability (VPN/proxy/firewall) if the body snippet is HTML instead of JSON.
Defensive patterns

Strategy: try-catch

Validate before calling

if (!state.apiKey.trim()) throw new Error("API key required before testing connection");
if (!provider.chatEndpoint || !/^https?:\/\//.test(provider.chatEndpoint)) throw new Error("Chat endpoint missing or invalid");

Try / catch

try {
  const response = await aiRequest(provider.chatEndpoint, "POST", headers, JSON.stringify(payload));
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${response.body.substring(0, 200)}`);
  }
  const data = JSON.parse(response.body);
} catch (err) {
  toast.error(t("Connection test failed") + ": " + err.message);
}

Prevention

When it happens

Trigger: Running the connection test for a chat provider; the completion endpoint returns 401 (bad key), 404 (wrong path/model), 400 (malformed request or unsupported parameter), 429 (quota/rate limit), or 5xx, with the provider's error JSON in the body.

Common situations: API key invalid/revoked or billing not enabled (OpenAI 429 insufficient_quota); selected model name not available to the account (404 model_not_found); base URL pointing to /v1/chat/completions on a server that uses another route; request blocked by proxy returning HTML (visible in the body snippet).

Related errors


AI-assisted analysis of koodo-reader/koodo-reader@7d40df41e0 (2026-08-29). Data as JSON: /api/errors/3ea7d57a3027a55c. Report an issue: GitHub.