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
- Read the embedded body in the message — it usually states the exact API error.
- Verify CF_API_TOKEN is valid and has D1 (account-level) read permission; regenerate if expired.
- Verify CF_ACCOUNT_ID matches the account owning the database.
- Run the SQL manually against the D1 console to catch syntax/schema errors.
- 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
- Rotate and scope API tokens before expiry; test with a cheap query first.
- Verify account ID against the dashboard URL.
- Validate SQL against the D1 console before shipping.
- Add bounded retry with backoff for 429/5xx.
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
- Cloudflare SQL response did not contain a data array
- Anthropic API error (HTTP )
- Cloud agent sandbox listing failed
- CNB pull request create failed
- Codewhale account request failed
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)