The bug
Including an emoji (specifically "🤖") in a markdown header causes a crash.
Minimal Repro
Tested against v5.0.1 and main@e3bae0071311d30a89b756919f1fe4800bb6a7cf
from textual.app import App, ComposeResult
from textual.widgets import Markdown
class TestApp(App):
"""Markdown append bug repro"""
def compose(self) -> ComposeResult:
yield Markdown("## 🤖 This heading is broken\n")
if __name__ == "__main__":
app = TestApp()
app.run()
Traceback
(captured in the console using markdown append, doesn't fail as loudly as the above repro but is easier to copy/paste the exception which is the same)
future: <_GatheringFuture finished exception=BadIdentifier("'heading-%F0%9F%A4%96-this-heading-is-broken-4381065296' is an invalid id; identifiers must contain only letters,
numbers, underscores, or hyphens, and must not begin with a number.")>
Traceback (most recent call last):
File "/Users/chris/bootloop/textual/src/textual/widgets/_markdown.py", line 1416, in await_append
new_blocks = list(self._parse_markdown(tokens))
File "/Users/chris/bootloop/textual/src/textual/widgets/_markdown.py", line 1274, in _parse_markdown
block.id = f"heading-{slug(block._content.plain)}-{id(block)}"
^^^^^^^^
File "/Users/chris/bootloop/textual/src/textual/dom.py", line 783, in id
check_identifiers("id", new_id)
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
File "/Users/chris/bootloop/textual/src/textual/dom.py", line 98, in check_identifiers
raise BadIdentifier(
...<2 lines>...
)
textual.dom.BadIdentifier: 'heading-%F0%9F%A4%96-this-heading-is-broken-4381065296' is an invalid id; identifiers must contain only letters, numbers, underscores, or hyphens, and
must not begin with a number.
Textual Diagnose Output
Textual Diagnostics
Versions
| Name |
Value |
| Textual |
5.0.1 |
| Rich |
14.1.0 |
Python
| Name |
Value |
| Version |
3.13.5 |
| Implementation |
CPython |
| Compiler |
Clang 20.1.4 |
| Executable |
/Users/chris/bootloop/textual-bug-test/.venv/bin/python3 |
Operating System
| Name |
Value |
| System |
Darwin |
| Release |
24.5.0 |
| Version |
Darwin Kernel Version 24.5.0: Tue Apr 22 19:54:43 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T8132 |
Terminal
| Name |
Value |
| Terminal Application |
iTerm.app (3.5.14) |
| TERM |
xterm-256color |
| COLORTERM |
truecolor |
| FORCE_COLOR |
Not set |
| NO_COLOR |
Not set |
Rich Console options
| Name |
Value |
| size |
width=123, height=43 |
| legacy_windows |
False |
| min_width |
1 |
| max_width |
123 |
| is_terminal |
True |
| encoding |
utf-8 |
| max_height |
43 |
| justify |
None |
| overflow |
None |
| no_wrap |
False |
| highlight |
None |
| markup |
None |
| height |
None |
The bug
Including an emoji (specifically "🤖") in a markdown header causes a crash.
Minimal Repro
Tested against v5.0.1 and main@e3bae0071311d30a89b756919f1fe4800bb6a7cf
Traceback
(captured in the console using markdown append, doesn't fail as loudly as the above repro but is easier to copy/paste the exception which is the same)
Textual Diagnose Output
Textual Diagnostics
Versions
Python
Operating System
Terminal
Rich Console options