Skip to content

id(web): saving a table cell with a hard break or a list panics in the markdown codec — ill-formed comrak AST #1017

Closed

Description

@dezren39

Summary

Saving a document whose table cell contains anything other than plain paragraph text can panic in the markdown codec: prosemirror_to_markdown builds an ill-formed comrak AST and format_commonmark panics instead of returning markdown (or an error).

Evidence (verified 2026-10-26 on main 786d2129, standalone verbatim-codec probe)

Probe: hidden_files/probe-2026-10-26-1615/ (crate = current pkgs/id/src/web/markdown.rs copied verbatim + round-trip harness).

Case 1 — a hard_break inside a table cell (PM JSON: table → table_row → table_cell → paragraph → text line1, hard_break, text line2):

thread 'main' panicked at comrak-0.56.0/src/cm.rs:29:9:
The document to format is ill-formed: InvalidChildType {
  parent: <TableCell> [<Text("line1")>, <LineBreak>, <Text("line2")>],
  child: <LineBreak> }

Case 2 — a bullet_list inside a table cell: same panic, InvalidChildType { parent: <TableCell>, child: <List …> }.

Root cause

pkgs/id/src/web/markdown.rs:1090-1110 (json_to_ast, table-cell special case): paragraph children are unwrapped inline into the cell, and any non-paragraph child is also appended directly to the cell node via append_inline_child (:1106) — including block nodes (lists, code blocks, quotes). hard_break maps to NodeValue::LineBreak (:1074), which comrak's CommonMark renderer also rejects as a direct child of TableCell. comrak validates the tree in format_commonmark and panics on the ill-formed AST; the codec returns Result<_, ConversionError> everywhere else, so this input escapes the error channel entirely. In the server this is a panic on the save path for a document the editor can plausibly produce (Shift+Enter inside a cell; pasted/structured content with a list in a cell).

Related, already tracked separately: multi-paragraph cells fuse words (#1003) — that is the paragraph-unwrap path; this issue is the non-paragraph / LineBreak path that crashes outright.

Acceptance criteria

  • prosemirror_to_markdown never panics for any PM doc the schema can express in a table cell; ill-supported cell content degrades to a defined representation (e.g. hard break → space or literal text; block content → flattened inline text) or returns ConversionError.
  • Regression tests in pkgs/id/src/web/markdown.rs covering at least: hard_break in a cell, list in a cell, code_block in a cell — each asserting a non-panicking, content-preserving-as-possible output and a stable second save (fixpoint).
  • Existing markdown codec tests still pass.

Suggested direction

In the table-cell special case, sanitize children before appending: convert LineBreak to a space/text node inside cells, and flatten non-inline block children to their inline text (or reject with ConversionError::UnknownType-style error) instead of attaching them under TableCell.

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    task/triageQueue packet kind: verify, reproduce, and route this item
    source/creatorFiled by the new-issue-creator job
    priority/normalOrdinary priority (the default)
    queue/queuedHas a queued task in the Supabase agent queue
    on Oct 26, 2026
  2. developing-today commented on Oct 26, 2026

    @developing-today
    Contributor
  3. added
    app/idPackage/app: id (pkgs/ or apps/ in this repo)
    on Oct 26, 2026
  4. dezren39 commented on Oct 26, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

    • Agent: new-issue-creator job
    • Session / ID: new-issue-creator cron run 2026-10-26 16:10 CDT
    • Found via: filed this run
    • Task: Verified with a standalone verbatim-codec probe on main 786d212 (logs hidden_files/probe-2026-10-26-1615/err.log + err2.log): PM table cells containing a hard_break or a bullet_list make prosemirror_to_markdown build an ill-formed comrak AST (LineBreak / List directly under TableCell, json_to_ast cell special case markdown.rs:1090-1110) and format_commonmark panics at comrak cm.rs:29 instead of returning markdown or an error. Enqueued as a triage packet to repo-health-code-pilot — the degradation choice for unsupported cell content needs a decision.
    • Expectation: triage decides the cell-content degradation rule; done when no PM cell content can panic the save path and regression tests cover hard_break/list/code_block cells.
    • Links: probe evidence in goal hidden_files (see issue body)
  5. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Oct 26, 2026
  6. 5 remaining items

  7. dezren39 commented on Oct 26, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · parked

  8. dezren39 commented on Oct 26, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  9. added
    queue/claimedQueue worker lifecycle state
    and removed
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Oct 26, 2026
  10. dezren39 commented on Oct 26, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/idPackage/app: id (pkgs/ or apps/ in this repo)kind/bugSomething isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)source/creatorFiled by the new-issue-creator jobstatus:donetask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions