Rich text editor rewrites adjacent references, intraword emphasis and quoted label references on save
Summary
Saving a description, comment or wiki page from the rich text editor rewrites three kinds of markdown, with no edit made:
- A space is inserted between a reference and the punctuation before it:
#1/#2is saved as#1/ #2,#1-#2as#1- #2,@root/@useras@root/ @user; the rendered text shows the stray space. - Emphasis inside a word is written with underscores:
a*b*c(italicb) is saved asa_b_c, which GitLab Flavored Markdown renders as literal text, so the emphasis is lost. - Quoted label and milestone references are written as HTML entities:
~"UX Paper Cuts"is saved as~"UX Paper Cuts"and%"17.5"as%"17.5". They still render, but the source is unreadable in the plain text editor, in diffs and in the description history.
Steps to reproduce
-
In a project with two issues, a label whose name contains a space (for example
UX Paper Cuts) and a milestone (for exampleSprint 1), set an issue description in the plain text editor to:Either #1/#2 fixes it. a*b*c Tracked under ~"UX Paper Cuts" for %"Sprint 1". -
Select Edit title and description, switch to rich text editing if the form opens in plain text, and select Save changes without editing.
-
Observe the rendered description:
Either #1/ #2 fixes it.(stray space) anda_b_cas literal text. -
Open the plain text editor: the description now reads
Either #1/ #2 fixes it.,a_b_c, andTracked under ~"UX Paper Cuts" for %"Sprint 1".
Example Project
Any project on GitLab.com. Reproduced on 2026-09-08 against the production markdown renderer (POST /api/v4/markdown, project gitlab-org/gitlab) fed through the editor's own deserializer and serializer.
What is the current bug behavior?
The three rewrites above happen on every save from the rich text editor, whether or not the text was edited.
What is the expected correct behavior?
Saving without edits leaves the markdown byte-identical: #1/#2, a*b*c, ~"UX Paper Cuts", %"Sprint 1".
Relevant logs and/or screenshots
Production HTML for ~"UX Paper Cuts" carries the reference as HTML-escaped text: data-original="~"UX Paper Cuts"". Deserializing then serializing #1/#2 with the editor's services gives #1/ #2; a*b*c gives a_b_c; ~"UX Paper Cuts" gives ~"UX Paper Cuts".
Output of checks
This bug happens on GitLab.com.
Possible fixes
- Adjacent references:
app/assets/javascripts/content_editor/services/serialization_helpers.js,ensureSpacewrites a space before every reference unless the output ends in whitespace, a bracket, a quote or a mark delimiter;/,-,+,=,|and&are not in the list. The markdown parser only needs the space after a letter, digit or underscore (which it reads as a project path,abc#1), so the rule should be inverted to that case. Introduced by Fix reference serialization in RTE (!165017). - Intraword emphasis:
app/assets/javascripts/content_editor/services/serializer/italic.jsalways writes_; CommonMark does not let_open or close emphasis next to a letter or digit. Write*when the emphasis touches a word character on either side. Introduced by Preserve bold, italic, code, and link syntax in the Content Editor (!87157). - Quoted references:
app/assets/javascripts/content_editor/extensions/reference.jsstoresdataset.originalwithout decoding it, whileBanzai::Filter::References::ReferenceFilter#data_attributes_forstoresdata-originalas HTML-escaped text. Decode when parsing, and escape<and>when the reference is written back so a label name with angle brackets is not parsed as an HTML tag. Present since Render references in content editor (!68230). - Two further shapes are covered by the same MR: a path-like word typed directly before a reference chip (
foo-then#1,v1.then#1) and a word typed directly after a chip (#1abc,~bugx,@root.x) both lose the reference on render, so the spacing rule writes the protecting space on both sides (foo- #1,#1 abc) unless the neighbour is punctuation that follows another reference (#1-#2stays tight).
Merge request: Fix reference spacing, intraword emphasis and quoted references on rich text editor save (!254251).
Fix: !254251