evanw/esbuild · error · LexerPanic

Expected identifier after %q in namespaced JSX name

Error message

Expected identifier after %q in namespaced JSX name

What it means

In parseJSXNamespacedName, after a ':' JSX namespace separator the next token must be an identifier. If it is anything else, esbuild reports the partial namespace (e.g. 'foo:') and the position right after it, then aborts.

Source

Thrown at internal/js_parser/js_parser.go:5192

	// Parse JSX namespaces. These are not supported by React or TypeScript
	// but someone using JSX syntax in more obscure ways may find a use for
	// them. A namespaced name is just always turned into a string so you
	// can't use this feature to reference JavaScript identifiers.
	if p.lexer.Token == js_lexer.TColon {
		// Parse the colon
		nameRange.Len = p.lexer.Range().End() - nameRange.Loc.Start
		ns := name.String + ":"
		p.lexer.NextInsideJSXElement()

		// Parse the second identifier
		if p.lexer.Token == js_lexer.TIdentifier {
			nameRange.Len = p.lexer.Range().End() - nameRange.Loc.Start
			ns += p.lexer.Identifier.String
			p.lexer.NextInsideJSXElement()
		} else {
			p.log.AddError(&p.tracker, logger.Range{Loc: logger.Loc{Start: nameRange.End()}},
				fmt.Sprintf("Expected identifier after %q in namespaced JSX name", ns))
			panic(js_lexer.LexerPanic{})
		}
		return nameRange, js_lexer.MaybeSubstring{String: ns}
	}

	return nameRange, name
}

func tagOrFragmentHelpText(tag string) string {
	if tag == "" {
		return "fragment tag"
	}
	return fmt.Sprintf("%q tag", tag)
}

func (p *parser) parseJSXTag() (logger.Range, string, js_ast.Expr) {
	loc := p.lexer.Loc()

	// A missing tag is a fragment

View on GitHub (pinned to f6058f8364)

Solutions

  1. Provide an identifier after the colon, e.g. '<foo:bar />'.
  2. Remove the colon if a namespace was not intended.
  3. Use a dotted member form '<foo.bar />' to reference nested objects.

Example fix

// before
<foo: />
// after
<foo:bar />
Defensive patterns

Strategy: validation

Validate before calling

import "github.com/evanw/esbuild/pkg/api"
opts := api.TransformOptions{Loader: api.LoaderJSX}
res := api.Transform(jsx, opts)
for _, m := range res.Errors {
  if strings.Contains(m.Text, "namespaced JSX name") {
    // a ':' in a tag was not followed by an identifier
  }
}

Type guard

// Flag JSX tags like <foo:>, <foo:123>.
var reBadNs = regexp.MustCompile(`<[-A-Za-z0-9]+:(?![-A-Za-z0-9])`)
func jsxNamespaceMissingIdent(src string) bool { return reBadNs.MatchString(src) }

Prevention

When it happens

Trigger: '<foo:>' or '<foo:123>' or '<foo:=bar />' — a ':' in a JSX tag/attribute name not followed by an identifier.

Common situations: Typing ':' instead of a name; auto-generated JSX with empty namespace segments; confusing XML-style namespaces with JSX member expressions.

Related errors


AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09). Data as JSON: /api/errors/e49afa4b3c2fa4a7. Report an issue: GitHub.