cube-js/cube · error
Unexpected names and types length mismatch; names ${names.le
Error message
Unexpected names and types length mismatch; names ${names.length} vs types ${types.length} What it means
In the JSONCompactEachRowWithNamesAndTypes response, the first row must be column names and the second row column types, and both must have the same number of elements. This error is thrown when the names row and types row lengths diverge, indicating a malformed or unexpected response from ClickHouse.
Source
Thrown at packages/cubejs-clickhouse-driver/src/ClickHouseDriver.ts:425
}
}());
const first = await allRowsIter.next();
if (first.done) {
throw new Error('Unexpected stream end before row with names');
}
// JSONCompactEachRowWithNamesAndTypes: expect first row to be column names as string
const names = first.value as Array<string>;
const second = await allRowsIter.next();
if (second.done) {
throw new Error('Unexpected stream end before row with types');
}
// JSONCompactEachRowWithNamesAndTypes: expect first row to be column names as string
const types = second.value as Array<string>;
if (names.length !== types.length) {
throw new Error(`Unexpected names and types length mismatch; names ${names.length} vs types ${types.length}`);
}
const dataRowsIter = (async function* () {
for await (const row of allRowsIter) {
yield transformStreamRow(row, names, types);
}
}());
const rowStream = Readable.from(dataRowsIter);
return {
rowStream,
types: names.map((name, idx) => {
const type = types[idx];
return {
name,
type: this.toGenericType(type),
};
}),View on GitHub (pinned to 7d981676b3)
Solutions
- Query ClickHouse directly with FORMAT JSONCompactEachRowWithNamesAndTypes to inspect the raw response for inconsistent row lengths
- Remove or reconfigure proxies/middlewares that could alter the streamed body
- Verify the endpoint is a genuine ClickHouse server (not an incompatible shim) and versions match driver expectations
- Upgrade the cubejs-clickhouse-driver package; if it persists, report with the query id
Example fix
// before (mock in tests returning inconsistent rows) ['id', 'name'] // names row ['UInt64'] // types row — wrong arity, triggers error // after ['id', 'name'] ['UInt64', 'String']
Defensive patterns
Strategy: validation
Validate before calling
// Sanity-check the server responds correctly to the format
const res = await fetch(`${clickhouseUrl}/?query=${encodeURIComponent('SELECT 1 FORMAT JSONCompactEachRowWithNamesAndTypes')}`);
const rows = await res.json();
if (!Array.isArray(rows) || rows.length < 2 || rows[0].length !== rows[1].length) throw new Error('Incompatible ClickHouse format response'); Type guard
const isWellFormedNamesTypes = (r: unknown): r is [string[], string[]] => Array.isArray(r) && r.length >= 2 && Array.isArray(r[0]) && Array.isArray(r[1]) && r[0].length === r[1].length;
Try / catch
try { return await driver.downloadQueryResults(q, v); }
catch (e) {
if (String(e.message).includes('names and types length mismatch')) throw new Error('ClickHouse returned malformed response; check server/proxy', { cause: e });
throw e;
} Prevention
- Test against the real ClickHouse server, not hand-rolled mocks
- Avoid middleboxes that rewrite streaming bodies
- Pin supported ClickHouse versions
When it happens
Trigger: Calling downloadQueryResults()/stream(); after reading the names row, the types row (second.value) has a different element count than names.length — only possible with a corrupted, non-standard, or intercepted response body.
Common situations: A proxy or middlebox rewriting/chunking the response incorrectly; a custom ClickHouse-compatible server that emits rows with inconsistent arity; manually mocked or stubbed ClickHouse responses in tests; format handling bugs after driver/server version changes.
Related errors
- Unexpected row and names/types length mismatch; row ${row.le
- Unexpected stream end before row with names
- Unexpected stream end before row with types
- Stream query failed: ${e}; query id: ${queryId}
- Invalid message format
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/356c66b04bb17b4a.
Report an issue: GitHub.