{"record":{"id":"99ff3d05b9d98857","repo":"facebook/react","slug":"invalid-tag-tag","errorCode":null,"errorMessage":"Invalid tag: ${tag}","messagePattern":"Invalid tag: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js","lineNumber":4210,"sourceCode":"      }\n    }\n  }\n  if (typeof children === 'string' && children[0] === '\\n') {\n    target.push(leadingNewline);\n  }\n  return children;\n}\n\n// We accept any tag to be rendered but since this gets injected into arbitrary\n// HTML, we want to make sure that it's a safe tag.\n// http://www.w3.org/TR/REC-xml/#NT-Name\nconst VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\\.\\-\\d]*$/; // Simplified subset\nconst validatedTagCache = new Map<string, PrecomputedChunk>();\nfunction startChunkForTag(tag: string): PrecomputedChunk {\n  let tagStartChunk = validatedTagCache.get(tag);\n  if (tagStartChunk === undefined) {\n    if (!VALID_TAG_REGEX.test(tag)) {\n      throw new Error(`Invalid tag: ${tag}`);\n    }\n\n    tagStartChunk = stringToPrecomputedChunk('<' + tag);\n    validatedTagCache.set(tag, tagStartChunk);\n  }\n  return tagStartChunk;\n}\n\nexport const doctypeChunk: PrecomputedChunk =\n  stringToPrecomputedChunk('<!DOCTYPE html>');\n\nimport {doctypeChunk as DOCTYPE} from 'react-server/src/ReactFizzConfig';\n\nexport function pushStartInstance(\n  target: Array<Chunk | PrecomputedChunk>,\n  type: string,\n  props: Object,\n  resumableState: ResumableState,","sourceCodeStart":4192,"sourceCodeEnd":4228,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js#L4192-L4228","documentation":"Thrown by startChunkForTag when an element's tag name fails VALID_TAG_REGEX (/^[a-zA-Z][a-zA-Z:_\\.\\-\\d]*$/ — start with a letter; then only letters, colons, underscores, dots, hyphens, digits). Because the tag is concatenated raw into the HTML output, this simplified XML-Name subset blocks injection of delimiters like spaces, quotes, '<', '>' or slashes; anything else aborts the render.","triggerScenarios":"React.createElement with a non-static tag string: tags starting with a digit (custom element '42-card'), containing spaces/slashes/quotes, empty or undefined-as-string tags, or user/CMS-supplied tag names interpolated into JSX: <[tag] /> via createElement(tag, props).","commonSituations":"Dynamic tag names from CMS data or markdown renderers; custom elements built from generated identifiers; template literals producing 'div extra' or 'a/b'; passing a component variable that is actually undefined so it coerces weirdly.","solutions":["Validate/normalize the tag before createElement: fall back to 'div' or 'span' for names failing /^[a-zA-Z][a-zA-Z:_\\-.\\d]*$/","Fix the producer of the name (strip namespaces, whitespace, angle brackets) at the data boundary","For custom elements, ensure the name matches the Custom Elements spec (lowercase, contains a hyphen, starts with a letter)"],"exampleFix":"// before\nconst Tag = cmsData.tagName; // e.g. \"42-card\" or \"div class=x\"\n< createElement(Tag, props) / >\n\n// after\nconst TAG_RE = /^[a-zA-Z][a-zA-Z:_\\-.\\d]*$/;\nconst Tag = TAG_RE.test(cmsData.tagName) ? cmsData.tagName : 'div';\nReact.createElement(Tag, props)","handlingStrategy":"validation","validationCode":"const VALID_TAG = /^[a-zA-Z][a-zA-Z:_\\-.\\d]*$/;\nfunction safeTag(tag: string, fallback: string = 'div'): string {\n  return typeof tag === 'string' && VALID_TAG.test(tag) ? tag : fallback;\n}\n// React.createElement(safeTag(cms.tagName), props)","typeGuard":"function isValidElementTag(tag: unknown): tag is string {\n  return typeof tag === 'string' && /^[a-zA-Z][a-zA-Z:_\\-.\\d]*$/.test(tag);\n}","tryCatchPattern":null,"preventionTips":["Never pass unvalidated external strings as element types; whitelist known tags","Normalize CMS/user-derived tag names (trim, strip namespaces/attributes) at the data boundary","Remember the rule: first char a letter; remaining chars letters, digits, ':', '_', '-', '.'"],"tags":["ssr","custom-elements","validation","injection","security"],"backgroundTag":"invalid-element-tag-name","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}