jackwener/OpenCLI · error · CommandExecutionError
Gemini transcript lines returned a malformed row
Error message
Gemini transcript lines returned a malformed row
What it means
Thrown by getGeminiTranscriptLines when requireGeminiArrayResult succeeds but the returned array contains non-string entries. The transcript-lines script must yield an array of plain strings; any object, null, or number in the array triggers this CommandExecutionError.
Source
Thrown at clis/gemini/utils.js:1201
const lines = await getGeminiTranscriptLines(page);
return lines.map((line) => ({ Role: 'System', Text: line }));
}
async function getGeminiStructuredTurns(page) {
await ensureGeminiPage(page);
const raw = requireGeminiArrayResult(await page.evaluate(getTurnsScript()), 'Gemini visible turns');
for (const turn of raw) {
if (!isObjectRecord(turn) || typeof turn.Role !== 'string' || typeof turn.Text !== 'string') {
throw new CommandExecutionError('Gemini visible turns returned a malformed row');
}
}
const turns = collapseAdjacentGeminiTurns(raw);
return Array.isArray(turns) ? turns : [];
}
export async function getGeminiTranscriptLines(page) {
await ensureGeminiPage(page);
const lines = requireGeminiArrayResult(await page.evaluate(getTranscriptLinesScript()), 'Gemini transcript lines');
if (!lines.every((line) => typeof line === 'string')) {
throw new CommandExecutionError('Gemini transcript lines returned a malformed row');
}
return lines;
}
export async function waitForGeminiTranscript(page, attempts = 5) {
let lines = [];
for (let index = 0; index < attempts; index += 1) {
lines = await getGeminiTranscriptLines(page);
if (lines.length > 0)
return lines;
if (index < attempts - 1)
await page.wait(1);
}
return lines;
}
export async function getLatestGeminiAssistantResponse(page) {
await ensureGeminiPage(page);
const turns = await getGeminiVisibleTurns(page);
const assistantTurn = [...turns].reverse().find((turn) => turn.Role === 'Assistant');View on GitHub (pinned to 49907e53dc)
Solutions
- Retry after a short wait for the transcript to finish rendering.
- Inspect raw output of getTranscriptLinesScript and coerce/map entries to strings inside the in-page script (e.g. el.textContent.trim()).
- Filter out null/undefined entries in the extraction script before returning.
- Catch CommandExecutionError and fall back to the structured-turns API instead.
Defensive patterns
Strategy: type-guard
Type guard
function isStringArray(v) {
return Array.isArray(v) && v.every((x) => typeof x === 'string');
} Try / catch
try {
lines = await getGeminiTranscriptLines(page);
} catch (e) {
if (String(e.message).includes('malformed row')) lines = [];
else throw e;
} Prevention
- Poll only after the transcript container is present and stable.
- Validate mocked data with isStringArray in tests.
- Keep extraction script in sync with Gemini transcript DOM changes.
- Prefer the structured-turns API when line-level detail isn't required.
When it happens
Trigger: Calling transcript-line extraction when getTranscriptLinesScript() returns mixed content (e.g. nested elements serialized as objects, undefined for empty line containers) because Gemini's transcript DOM changed or the page was polled mid-render.
Common situations: Gemini update changing line container structure; transcript containing rich nodes (images/code) that the script maps to objects; stale page snapshot from before hydration; mocked data of the wrong shape.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Gemini conversation list returned a malformed row
- Gemini visible turns returned a malformed row
- Gemini generation probe returned a malformed result
- Gemini page snapshot returned a malformed result
- Gemini image detection returned a malformed result
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/cf306c2296613824.
Report an issue: GitHub.