Nested markdown lists: first item of a 3rd-level list is indented 2 spaces too deep

Status Fixed / completed
Reported on v2.1.220
Maintainer reply None cached
Activity 2 comments · opened Jul 31, 2026 · closed Aug 20, 2026

Environment

  • Claude Code 2.1.220 (native install)
  • macOS (Darwin 25.5.0), node v20.19.6

What happens

When assistant output contains a markdown list nested 3 levels deep, the first item of
the deepest list is rendered 2 spaces deeper than its siblings.

Source (assistant message text):

  • L1
  • L2
  • item A
  • item B

Rendered in the terminal:

  • L1
  • L2
  • item A <- 6 spaces
  • item B <- 4 spaces

Expected: item A and item B share the same indentation.
Two-level lists render correctly.

Cause

In the markdown-to-terminal renderer, list_item stringifies each child token and
prefixes the parent indent to that whole string. A nested list is a multi-line string,
so the parent indent lands on its first line only:

case "list_item": return (e.tokens ?? []).map((child) => {
    const d = render(child, { listDepth: n + 1, ... });
    return `${"  ".repeat(n)}${d}`;   // applied to the entire multi-line string
  }).join("")

Two-level lists are unaffected because the parent's n is 0.

Repro (extracted logic, plain node)

const NL = "\n";
function render(tok, n = 0, parent = null) {
  switch (tok.type) {
    case "list": return tok.items.map((it) => render(it, n, tok)).join("");
    case "list_item": return (tok.tokens || []).map((child) => "  ".repeat(n) + render(child, n + 1, tok)).join("");
    case "text": return parent && parent.type === "list_item" ? `- ${tok.text}${NL}` : tok.text;
  }
}
const row = (t) => ({ type: "list_item", tokens: [{ type: "text", text: t }] });
const nest = (label, inner) => ({ type: "list_item", tokens: [{ type: "text", text: label }, inner] });
const three = { type: "list", items: [nest("L1", { type: "list", items: [nest("L2", { type: "list", items: [row("item A"), row("item B")] })] })] };
console.log(render(three));
// => item A gets 6 spaces, item B gets 4

Non-workarounds

Changing the source indent width (2 / 4 / 6 spaces, tabs), changing the bullet marker,
inserting blank lines between items, and reordering items all fail — the displayed
indent is generated from listDepth, not from the source whitespace.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗