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
- Add the matching closing tag '</tagName>'.
- Self-close the element with '/>' if it has no children.
- 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
- Use a JSX-aware editor/eslint-plugin-react that balances tags.
- Self-close elements with '/>' when they have no children.
- Run tsc --jsx on .tsx files to catch unclosed elements before bundling.
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
- Expected identifier after %q in namespaced JSX name
- Unexpected "-"
- Unexpected backslash in JSX element
- Unexpected newline before "=>"
- For loop initializers cannot start with "async of"
AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09).
Data as JSON: /api/errors/f6a9438de23ef959.
Report an issue: GitHub.