evanw/esbuild · error · LexerPanic

Unexpected end of file before a closing %s

Error message

Unexpected end of file before a closing %s

What it means

While parsing a JSX element, the lexer reached end-of-file before the matching closing tag. esbuild reports the opening tag location and suggests the exact '</tagName>' to add.

Source

Thrown at internal/js_parser/js_parser.go:5554

			return js_ast.Expr{Loc: loc, Data: &js_ast.EJSXElement{
				TagOrNil:         startTagOrNil,
				Properties:       properties,
				NullableChildren: nullableChildren,
				CloseLoc:         lessThanLoc,
				IsTagSingleLine:  isSingleLine,
			}}

		case js_lexer.TEndOfFile:
			startTag := tagOrFragmentHelpText(startText)
			msg := logger.Msg{
				Kind:  logger.Error,
				Data:  p.tracker.MsgData(p.lexer.Range(), fmt.Sprintf("Unexpected end of file before a closing %s", startTag)),
				Notes: []logger.MsgData{p.tracker.MsgData(startRange, fmt.Sprintf("The opening %s is here:", startTag))},
			}
			msg.Data.Location.Suggestion = fmt.Sprintf("</%s>", startText)
			p.log.AddMsg(msg)
			panic(js_lexer.LexerPanic{})

		default:
			p.lexer.Unexpected()
		}
	}
}

func (p *parser) parseTemplateParts(includeRaw bool) (parts []js_ast.TemplatePart, legacyOctalLoc logger.Loc) {
	// Allow "in" inside template literals
	oldAllowIn := p.allowIn
	p.allowIn = true

	for {
		p.lexer.Next()
		value := p.parseExpr(js_ast.LLowest)
		tailLoc := p.lexer.Loc()
		p.lexer.RescanCloseBraceAsTemplateToken()
		if includeRaw {

View on GitHub (pinned to f6058f8364)

Solutions

  1. Add the matching closing tag '</tagName>'.
  2. Self-close the element with '/>' if it has no children.
  3. Check for accidentally commented-out or deleted closing tags.

Example fix

// before
<div>hello
// after
<div>hello</div>
Defensive patterns

Strategy: validation

Validate before calling

import "github.com/evanw/esbuild/pkg/api"
res := api.Transform(jsx, api.TransformOptions{Loader: api.LoaderJSX})
for _, m := range res.Errors {
  if strings.Contains(m.Text, "Unexpected end of file before a closing") {
    // m.Location + notes point at the unclosed opening tag
  }
}

Prevention

When it happens

Trigger: '<div>...' with no '</div>' before EOF, or an unbalanced/self-closing element missing its '/>'.

Common situations: Truncated file; forgotten closing tag; a nested child element that swallowed the close; commented-out closing tag.

Related errors


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