Hmbown/CodeWhale · error · Error
Cloudflare SQL response did not contain a data array
Error message
Cloudflare SQL response did not contain a data array
What it means
dataRows extracts the row array from a Cloudflare SQL API response: either the payload itself is an array, or payload.data must be one. If the shape does not match — an error object, a string, or null came back — it throws 'Cloudflare SQL response did not contain a data array'. rowsFromResponse and newestEventFromResponse both depend on this extraction.
Source
Thrown at telemetry-ingest/scripts/report-active-installs.mjs:79
WHERE timestamp >= toStartOfDay(NOW()) - INTERVAL '${days - 1}' DAY
AND blob1 = 'session_start'
GROUP BY day
ORDER BY day DESC
FORMAT JSON`;
}
/** Newest ingested event of any kind — how stale the dataset is. */
export function freshnessSql() {
return `SELECT
max(timestamp) AS newest_event
FROM codewhale_telemetry
FORMAT JSON`;
}
function dataRows(payload) {
const rows = Array.isArray(payload) ? payload : payload?.data;
if (!Array.isArray(rows)) {
throw new Error("Cloudflare SQL response did not contain a data array");
}
return rows;
}
export function rowsFromResponse(payload) {
return dataRows(payload).map((row) => ({
day: String(row.day),
active_installs: Number(row.active_installs),
sessions_started: Number(row.sessions_started),
}));
}
/** `null` when the dataset has no rows at all. */
export function newestEventFromResponse(payload) {
const raw = dataRows(payload)[0]?.newest_event;
if (raw === undefined || raw === null || String(raw).startsWith("0000")) {
return null;
}View on GitHub (pinned to 8880682c63)
Solutions
- Log the raw payload before parsing to see the actual shape that arrived
- Re-issue the query via the Cloudflare dashboard/API and compare response shapes
- If the schema changed, update dataRows to read the new field while keeping the Array.isArray guard
Example fix
// before
const rows = payload?.data;
// after
const rows = Array.isArray(payload) ? payload : payload?.data;
if (!Array.isArray(rows)) {
throw new Error('Cloudflare SQL response did not contain a data array');
} Defensive patterns
Strategy: type-guard
Validate before calling
if (!isSqlRowsPayload(payload)) {
console.error('unexpected Cloudflare SQL payload shape:', JSON.stringify(payload).slice(0, 200));
process.exit(2);
} Type guard
function isSqlRowsPayload(payload) {
return Array.isArray(payload) || Array.isArray(payload?.data);
} Try / catch
try {
rowsFromResponse(payload);
} catch (error) {
if (/did not contain a data array/.test(error.message)) {
console.error('Cloudflare SQL payload changed — inspect raw response');
process.exit(2);
}
throw error;
} Prevention
- Log the raw payload shape when integrating so schema drift is visible
- Keep extraction behind one Array.isArray-guarded helper instead of ad-hoc field access
When it happens
Trigger: The SQL endpoint returning HTTP 200 with a body lacking a data array (error/status object, wrapped payload, changed response schema); passing a parsed body from a different endpoint version.
Common situations: Cloudflare API evolution changing the envelope; a proxied or transformed response; empty responses on brand-new accounts with no telemetry rows.
Related errors
- Cloudflare SQL request failed (${response.status}): ${body}
- DeepSeek ${res.status}: ${text}
- DeepSeek ${res.status}: ${text}
- Runtime API request failed (${status}): ${message}
- Runtime API request failed (${status}): ${message}
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/a534dd385727779c.
Report an issue: GitHub.