facebook/react · error · Error

Invalid tag: ${tag}

Error message

Invalid tag: ${tag}

What it means

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.

Source

Thrown at packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js:4210

      }
    }
  }
  if (typeof children === 'string' && children[0] === '\n') {
    target.push(leadingNewline);
  }
  return children;
}

// We accept any tag to be rendered but since this gets injected into arbitrary
// HTML, we want to make sure that it's a safe tag.
// http://www.w3.org/TR/REC-xml/#NT-Name
const VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\.\-\d]*$/; // Simplified subset
const validatedTagCache = new Map<string, PrecomputedChunk>();
function startChunkForTag(tag: string): PrecomputedChunk {
  let tagStartChunk = validatedTagCache.get(tag);
  if (tagStartChunk === undefined) {
    if (!VALID_TAG_REGEX.test(tag)) {
      throw new Error(`Invalid tag: ${tag}`);
    }

    tagStartChunk = stringToPrecomputedChunk('<' + tag);
    validatedTagCache.set(tag, tagStartChunk);
  }
  return tagStartChunk;
}

export const doctypeChunk: PrecomputedChunk =
  stringToPrecomputedChunk('<!DOCTYPE html>');

import {doctypeChunk as DOCTYPE} from 'react-server/src/ReactFizzConfig';

export function pushStartInstance(
  target: Array<Chunk | PrecomputedChunk>,
  type: string,
  props: Object,
  resumableState: ResumableState,

View on GitHub (pinned to eafeac097b)

Solutions

  1. Validate/normalize the tag before createElement: fall back to 'div' or 'span' for names failing /^[a-zA-Z][a-zA-Z:_\-.\d]*$/
  2. Fix the producer of the name (strip namespaces, whitespace, angle brackets) at the data boundary
  3. For custom elements, ensure the name matches the Custom Elements spec (lowercase, contains a hyphen, starts with a letter)

Example fix

// before
const Tag = cmsData.tagName; // e.g. "42-card" or "div class=x"
< createElement(Tag, props) / >

// after
const TAG_RE = /^[a-zA-Z][a-zA-Z:_\-.\d]*$/;
const Tag = TAG_RE.test(cmsData.tagName) ? cmsData.tagName : 'div';
React.createElement(Tag, props)
Defensive patterns

Strategy: validation

Validate before calling

const VALID_TAG = /^[a-zA-Z][a-zA-Z:_\-.\d]*$/;
function safeTag(tag: string, fallback: string = 'div'): string {
  return typeof tag === 'string' && VALID_TAG.test(tag) ? tag : fallback;
}
// React.createElement(safeTag(cms.tagName), props)

Type guard

function isValidElementTag(tag: unknown): tag is string {
  return typeof tag === 'string' && /^[a-zA-Z][a-zA-Z:_\-.\d]*$/.test(tag);
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of facebook/react@eafeac097b (2026-08-21). Data as JSON: /api/errors/99ff3d05b9d98857. Report an issue: GitHub.