{"record":{"id":"e61be4da8352ff4f","repo":"swc-project/swc","slug":"end-tag-end-tag-name-did-not-match-the-name-of","errorCode":null,"errorMessage":"End tag \"{end_tag_name}\" did not match the name of the current open element (\"{current_element_tag_name}\")","messagePattern":"End tag \"(.+?)\" did not match the name of the current open element \\(\"(.+?)\"\\)","errorType":"exception","errorClass":"swc_html_parser::error::Error","httpStatus":null,"severity":"warning","filePath":"crates/swc_html_parser/src/parser/mod.rs","lineNumber":807,"sourceCode":"                tag_name,\n                attributes,\n                ..\n            } if tag_name == \"font\"\n                && attributes\n                    .iter()\n                    .any(|attribute| matches!(&*attribute.name, \"color\" | \"face\" | \"size\")) =>\n            {\n                self.errors.push(Error::new(\n                    token_and_info.span,\n                    ErrorKind::HtmlStartTagInForeignContext(tag_name.clone()),\n                ));\n                self.open_elements_stack.pop_until_in_foreign();\n                self.process_token(token_and_info, None)?;\n            }\n            Token::EndTag { tag_name, .. } if matches!(&**tag_name, \"br\" | \"p\") => {\n                let last = get_tag_name!(self.open_elements_stack.items.last().unwrap());\n\n                self.errors.push(Error::new(\n                    token_and_info.span,\n                    ErrorKind::EndTagDidNotMatchCurrentOpenElement(tag_name.clone(), last.into()),\n                ));\n                self.open_elements_stack.pop_until_in_foreign();\n                self.process_token(token_and_info, None)?;\n            }\n            // Any other start tag\n            //\n            // If the adjusted current node is an element in the MathML namespace, adjust MathML\n            // attributes for the token. (This fixes the case of MathML attributes that are not all\n            // lowercase.)\n            //\n            // If the adjusted current node is an element in the SVG namespace, and the token's tag\n            // name is one of the ones in the first column of the following table, change the tag\n            // name to the name given in the corresponding cell in the second column. (This fixes\n            // the case of SVG elements that are not all lowercase.)\n            //\n            // Tag name\t            Element name","sourceCodeStart":789,"sourceCodeEnd":825,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_html_parser/src/parser/mod.rs#L789-L825","documentation":"An end tag `</br>` or `</p>` was processed while the current node was a foreign (SVG/MathML) element (crates/swc_html_parser/src/parser/mod.rs:807). The parser reports EndTagDidNotMatchCurrentOpenElement with the innermost open element's name, runs pop_until_in_foreign(), and reprocesses the token with HTML rules. The HTML element named by the end tag was never open in the foreign subtree.","triggerScenarios":"`</p>` or `</br>` inside an <svg>/<math> subtree, e.g. `<svg><text>hi</p></svg>`. Frequently the tail of a missing foreign-element boundary: after an unclosed <svg>/<math>, subsequent end tags are dispatched to foreign content until a breakout token resets the mode.","commonSituations":"Templates that conditionally emit the closing </svg> but always emit a trailing </p>, minified or machine-mangled markup, hand-edited SVG islands in HTML pages.","solutions":["Balance the end tag: close <p> where it was opened, outside the foreign subtree","Fix the unclosed <svg>/<math> so following end tags are handled by HTML rules","Treat the error as informational when the auto-close-and-reprocess recovery is acceptable"],"exampleFix":"<!-- before -->\n<svg><text>hi</p></svg>\n\n<!-- after -->\n<svg><text>hi</text></svg>","handlingStrategy":"validation","validationCode":"const VOID: &[&str] = &[\"area\",\"base\",\"br\",\"col\",\"embed\",\"hr\",\"img\",\"input\",\"link\",\"meta\",\"param\",\"source\",\"track\",\"wbr\"];\n\n// Heuristic stack checker: flags end tags that do not match the innermost open tag.\nfn find_mismatched_end_tags(html: &str) -> Vec<String> {\n    let lower = html.to_ascii_lowercase();\n    let mut stack: Vec<String> = Vec::new();\n    let mut bad = Vec::new();\n    for (i, _) in lower.match_indices('<') {\n        let rest = &lower[i + 1..];\n        let (closing, body) = match rest.strip_prefix('/') {\n            Some(b) => (true, b),\n            None => (false, rest),\n        };\n        let name: String = body.chars().take_while(char::is_ascii_alphanumeric).collect();\n        if name.is_empty() { continue; }\n        if closing {\n            match stack.last() {\n                Some(open) if open == &name => { stack.pop(); }\n                _ => bad.push(format!(\"</{}> at byte {}\", name, i)),\n            }\n        } else if !VOID.contains(&name.as_str()) {\n            stack.push(name);\n        }\n    }\n    bad\n}","typeGuard":null,"tryCatchPattern":"use swc_html_parser::error::ErrorKind;\n\nlet mut errors = Vec::new();\nlet doc = swc_html_parser::parse_file_as_document(&fm, config, &mut errors)?;\n\nfor err in &errors {\n    if let ErrorKind::EndTagDidNotMatchCurrentOpenElement(end, current) = err.kind() {\n        // Foreign content was force-closed so </p> could be reprocessed as HTML\n        log::warn!(\"</{}> saw open <{}>\", end, current);\n    }\n}","preventionTips":["Keep open/close pairs for p and br inside the HTML (non-foreign) part of the document","Close foreign elements explicitly before resuming HTML markup","Render conditional closers together with their openers in templates"],"tags":["html","parser","foreign-content","end-tag","mismatch","nesting","swc"],"backgroundTag":"mismatched-end-tag","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}