Hmbown/CodeWhale · error · Error

Cloudflare SQL request failed

Error message

Cloudflare SQL request failed (${response.status}): ${body}

What it means

querySql() POSTs a SQL statement to the Cloudflare D1 HTTP endpoint and throws when the HTTP response status is not OK, embedding the status code and the first 500 characters of the response body so the API-side error (auth, bad SQL, account issues) is visible.

Solutions

  1. Read the embedded body in the message — it usually states the exact API error.
  2. Verify CF_API_TOKEN is valid and has D1 (account-level) read permission; regenerate if expired.
  3. Verify CF_ACCOUNT_ID matches the account owning the database.
  4. Run the SQL manually against the D1 console to catch syntax/schema errors.
  5. Retry with backoff if status is 429 or 5xx.

Example fix

// before
const res = await fetch(url, { method: "POST", headers, body: sql });
// after
const res = await fetch(url, { method: "POST", headers, body: sql });
if (res.status === 429 || res.status >= 500) await new Promise(r => setTimeout(r, 2000)); // retry once
Defensive patterns

Strategy: retry

Validate before calling

if (!env.CF_ACCOUNT_ID?.trim() || !env.CF_API_TOKEN?.trim()) throw new Error("credentials missing before request");

Try / catch

try { await querySql(opts); } catch (e) { if (/failed \((\d{3})\)/.test(e.message)) { const status = +RegExp.$1; if (status === 429 || status >= 500) retryWithBackoff(); } throw e; }

Prevention

When it happens

Trigger: Any D1 HTTP query where response.ok is false: invalid/expired CF_API_TOKEN (401/403), wrong account ID (404), malformed SQL (400), rate limits (429), or D1 unavailable (5xx).

Common situations: Expired or wrongly-scoped API token; account ID copied from the wrong resource; SQL syntax error after a schema change; network proxy returning an HTML error page.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/46c8011dc4a9d9a8. Report an issue: GitHub.

Appendix: source

Thrown at telemetry-ingest/scripts/report-active-installs.mjs:210

  lines.push("", "Caveats:");
  for (const caveat of COVERAGE_CAVEATS) {
    lines.push(`  - ${caveat}`);
  }
  return lines.join("\n");
}

async function querySql({ accountId, apiToken, sql, fetchImpl = fetch }) {
  const response = await fetchImpl(SQL_ENDPOINT(accountId), {
    method: "POST",
    headers: {
      Authorization: `Bearer ${apiToken}`,
      "content-type": "text/plain; charset=utf-8",
    },
    body: sql,
  });
  if (!response.ok) {
    const body = (await response.text()).slice(0, 500);
    throw new Error(`Cloudflare SQL request failed (${response.status}): ${body}`);
  }
  return response.json();
}

export async function main(argv = process.argv.slice(2), env = process.env) {
  const { days, json } = parseArgs(argv);
  const accountId = env.CF_ACCOUNT_ID?.trim();
  const apiToken = env.CF_API_TOKEN?.trim();
  if (!accountId || !apiToken) {
    throw new Error("CF_ACCOUNT_ID and CF_API_TOKEN are required");
  }
  const rows = rowsFromResponse(
    await querySql({ accountId, apiToken, sql: activeInstallsSql(days) }),
  );
  const newestEvent = newestEventFromResponse(
    await querySql({ accountId, apiToken, sql: freshnessSql() }),
  );
  const now = new Date();

View on GitHub (pinned to 433685b202)