jackwener/OpenCLI · error · CommandExecutionError

Gmail returned a malformed label at index ${index}

Error message

Gmail returned a malformed label at index ${index}

What it means

In parseLabels, each row of body[1] should be a wrapper whose [0] is a label record starting with a label id at index 0. If cleanString(record?.[0]) is empty, this CommandExecutionError is thrown with the row index. A label without an id cannot be used in queries or as a target, so the parser rejects the row.

Source

Thrown at clis/gmail/utils.js:187

    if (!id) continue;
    result.set(id, {
      unread: Number.isFinite(Number(row?.[1])) ? Number(row[1]) : null,
      total: Number.isFinite(Number(row?.[2])) ? Number(row[2]) : null,
    });
  }
  return result;
}

export function parseLabels(body) {
  if (!Array.isArray(body) || body.length !== 19) {
    throw new CommandExecutionError('Gmail batch-view response had an unexpected shape');
  }
  const counts = labelCounts(body[6]);
  const rows = Array.isArray(body[1]) ? body[1] : [];
  return rows.map((wrapper, index) => {
    const record = Array.isArray(wrapper?.[0]) ? wrapper[0] : null;
    const id = cleanString(record?.[0]);
    if (!id) throw new CommandExecutionError(`Gmail returned a malformed label at index ${index}`);
    const count = counts.get(id) || {};
    return {
      id,
      name: cleanString(record?.[1]) || id,
      type: id.startsWith('^x_') ? 'user' : 'system',
      unreadCount: count.unread ?? null,
      totalCount: count.total ?? null,
    };
  });
}

function senderFromRecord(record) {
  const card = Array.isArray(record?.[10]) ? record[10] : null;
  const address = cleanString(card?.[16]);
  if (!address.includes('@')) return null;
  return { address, name: cleanString(card?.[14]) || null };
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry — transient placeholder rows typically resolve once Gmail finishes syncing labels.
  2. Update opencli if Gmail changed the label record layout.
  3. Reload Gmail so the labels settings data loads completely, then rerun.
  4. Avoid editing labels in another tab/session while running the command.
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

function isLabelRecord(wrapper) {
  const record = Array.isArray(wrapper?.[0]) ? wrapper[0] : null;
  return typeof record?.[0] === 'string' && record[0].trim().length > 0;
}

Try / catch

try {
  labels = await gmailLabels();
} catch (error) {
  if (String(error.message).includes('malformed label at index')) {
    await sleep(1500); // let label sync placeholders settle
    labels = await gmailLabels();
  } else throw error;
}

Prevention

When it happens

Trigger: A /i/bv labels payload containing a row whose label record is missing or has an empty id at index 0 — placeholder rows during live sync, or Gmail changing the per-label record layout.

Common situations: Users creating/deleting labels in another session while gmail labels runs, Gmail A/B experiments changing record field order, partially loaded label lists.

Understand the failure class

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/ace932234050096d. Report an issue: GitHub.