{"record":{"id":"2de742aca7e7857a","repo":"swc-project/swc","slug":"start-tag-tag-name-seen-but-an-element-of-the","errorCode":null,"errorMessage":"Start tag \"{tag_name}\" seen but an element of the same type was already open","messagePattern":"Start tag \"(.+?)\" seen but an element of the same type was already open","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"crates/swc_html_parser/src/parser/mod.rs","lineNumber":3513,"sourceCode":"                            let mut node = None;\n\n                            for element in self.active_formatting_elements.items.iter().rev() {\n                                match element {\n                                    ActiveFormattingElement::Marker => {\n                                        break;\n                                    }\n                                    ActiveFormattingElement::Element(item, _) => {\n                                        if is_html_element!(item, \"a\") {\n                                            node = Some(item);\n\n                                            break;\n                                        }\n                                    }\n                                }\n                            }\n\n                            if let Some(element) = node {\n                                self.errors.push(Error::new(\n                                    token_and_info.span,\n                                    ErrorKind::SomethingSeenWhenSomethingOpen(tag_name.clone()),\n                                ));\n\n                                let remove = element.clone();\n\n                                self.run_the_adoption_agency_algorithm(token_and_info, false)?;\n                                self.active_formatting_elements.remove(&remove);\n                                self.open_elements_stack.remove(&remove);\n                            }\n                        }\n\n                        self.reconstruct_active_formatting_elements()?;\n\n                        let element = self.insert_html_element(token_and_info)?;\n\n                        self.active_formatting_elements\n                            .push(ActiveFormattingElement::Element(","sourceCodeStart":3495,"sourceCodeEnd":3531,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_html_parser/src/parser/mod.rs#L3495-L3531","documentation":"A start tag `a` was found while the list of active formatting elements already contains an `a` element between the end of the list and the last marker (parser/mod.rs:3494-3515). HTML forbids nested anchors, so the parser records `SomethingSeenWhenSomethingOpen(\"a\")`, runs the adoption agency algorithm, and removes the old anchor from the active formatting list and the open elements stack before inserting the new one.","triggerScenarios":"Input like `<a href=\"/1\">first <a href=\"/2\">second</a></a>` — the second `<a>` start tag with an unclosed `<a>` still active. Also happens when templating loops concatenate link partials without closing the previous anchor.","commonSituations":"CMS rich-text editors that allow nested links, string concatenation of link fragments in server templates (`\"<a>\" + user1 + \"<a>\" + user2`), and scraped/legacy pages. Browsers silently unwrap the nesting; this error tells you the tree will be reshaped by the adoption agency algorithm.","solutions":["Close the previous anchor before opening the next: `<a>first</a> <a>second</a>`","Fix the template loop/generator so each emitted anchor is fully closed","Sanitize input with a whitelist-based sanitizer that auto-balances tags before parsing","Check `take_errors()` for `SomethingSeenWhenSomethingOpen` and reject/repair nested-link input"],"exampleFix":"<!-- before -->\n<a href=\"/a\">first <a href=\"/b\">second</a></a>\n\n<!-- after -->\n<a href=\"/a\">first</a> <a href=\"/b\">second</a>","handlingStrategy":"validation","validationCode":"// Detect nested anchors before parsing\nfn has_nested_anchor(src: &str) -> bool {\n    let mut a_open = false;\n    for tag in html_tag_tokens(src) {\n        match tag {\n            Start(ref n) if n == \"a\" => { if a_open { return true; } a_open = true; }\n            End(ref n) if n == \"a\" => a_open = false,\n            _ => {}\n        }\n    }\n    false\n}","typeGuard":"fn is_nested_anchor_error(e: &Error) -> bool {\n    matches!(e.kind, ErrorKind::SomethingSeenWhenSomethingOpen(ref t) if &**t == \"a\")\n}","tryCatchPattern":"let doc = parser.parse_document()?;\nlet nested = parser.take_errors().into_iter().any(is_nested_anchor_error);\nif nested {\n    // adoption agency already flattened the anchors; decide whether to reject input\n    return Err(ContentRejected::NestedAnchors);\n}","preventionTips":["Never concatenate link partials without closing the previous anchor","Run sanitize-html / DOMPurify with balanced-tag enforcement on user HTML","Unit-test rich-text renderers for the 'link inside link' case"],"tags":["html","parser","anchor","nesting","formatting-elements"],"backgroundTag":"nested-anchor-tags","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"}