diff --git a/templates/zerver/tests/markdown/test_tabbed_sections_missing_tabs.md b/templates/zerver/tests/markdown/test_tabbed_sections_missing_tabs.md
new file mode 100644
index 0000000000..023d0464a0
--- /dev/null
+++ b/templates/zerver/tests/markdown/test_tabbed_sections_missing_tabs.md
@@ -0,0 +1,11 @@
+# Heading
+
+{start_tabs}
+{tab|ios}
+iOS instructions
+
+{tab|minix}
+
+Minix instructions. We expect an exception because the minix tab doesn't have a declared label.
+
+{end_tabs}
diff --git a/zerver/lib/markdown/tabbed_sections.py b/zerver/lib/markdown/tabbed_sections.py
index ce7c866a52..594f39a6c5 100644
--- a/zerver/lib/markdown/tabbed_sections.py
+++ b/zerver/lib/markdown/tabbed_sections.py
@@ -27,7 +27,7 @@ NAV_BAR_TEMPLATE = """
""".strip()
NAV_LIST_ITEM_TEMPLATE = """
-
{name}
+{label}
""".strip()
DIV_TAB_CONTENT_TEMPLATE = """
@@ -141,10 +141,16 @@ class TabbedSectionsPreprocessor(Preprocessor):
def generate_nav_bar(self, tab_section: Dict[str, Any]) -> str:
li_elements = []
for tab in tab_section["tabs"]:
- li = NAV_LIST_ITEM_TEMPLATE.format(
- data_language=tab.get("tab_name"), name=TAB_SECTION_LABELS.get(tab.get("tab_name"))
- )
+ tab_name = tab.get("tab_name")
+ tab_label = TAB_SECTION_LABELS.get(tab_name)
+ if tab_label is None:
+ raise ValueError(
+ f"Tab '{tab_name}' is not present in TAB_SECTION_LABELS in zerver/lib/markdown/tabbed_sections.py"
+ )
+
+ li = NAV_LIST_ITEM_TEMPLATE.format(data_language=tab_name, label=tab_label)
li_elements.append(li)
+
return NAV_BAR_TEMPLATE.format(tabs="\n".join(li_elements))
def parse_tabs(self, lines: List[str]) -> Optional[Dict[str, Any]]:
diff --git a/zerver/tests/test_templates.py b/zerver/tests/test_templates.py
index 851e9d27db..0fa61f41b3 100644
--- a/zerver/tests/test_templates.py
+++ b/zerver/tests/test_templates.py
@@ -92,6 +92,15 @@ footer
expected_html_sans_whitespace = expected_html.replace(" ", "").replace("\n", "")
self.assertEqual(content_sans_whitespace, expected_html_sans_whitespace)
+ def test_markdown_tabbed_sections_missing_tabs(self) -> None:
+ template = get_template("tests/test_markdown.html")
+ context = {
+ "markdown_test_file": "zerver/tests/markdown/test_tabbed_sections_missing_tabs.md",
+ }
+ expected_regex = "^Tab 'minix' is not present in TAB_SECTION_LABELS in zerver/lib/markdown/tabbed_sections.py$"
+ with self.assertRaisesRegex(ValueError, expected_regex):
+ template.render(context)
+
def test_markdown_nested_code_blocks(self) -> None:
template = get_template("tests/test_markdown.html")
context = {