-
-
Notifications
You must be signed in to change notification settings - Fork 349
Description
Describe the bug
templ lsp crashes with a panic: runtime error: invalid memory address or nil pointer dereference upon initial opening of a templ file in neovim with nvim/nvim-lspconfig.
To Reproduce
Minimal crashing example, all 3 files in root folder
go.modmodule example.com go 1.25.2 require github.com/a-h/templ v0.3.960go.sumgithub.com/a-h/templ v0.3.960 h1:trshEpGa8clF5cdI39iY4ZrZG8Z/QixyzEyUnA7feTM= github.com/a-h/templ v0.3.960/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo=form.templpackage ui templ form()
Expected behavior
LSP should not panic.
Logs
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x20 pc=0x10111dccc]
github.com/a-h/templ/parser/v2.(*SourceMap).SourcePositionFromTarget(...)
/Users/REDACTED/.local/share/mise/installs/go/1.25.2/packages/pkg/mod/github.com/a-h/templ@v0.3.960/parser/v2/sourcemap.go:123
github.com/a-h/templ/cmd/templ/lspcmd/proxy.Client.PublishDiagnostics({0x1400003e840, {0x1013fb9d0, 0x1400000f230}, 0x1400003e8a0, 0x1400003e8b0}, {0x1013f7c08, 0x14000232c90}, 0x1400070c480)
/Users/REDACTED/.local/share/mise/installs/go/1.25.2/packages/pkg/mod/github.com/a-h/templ@v0.3.960/cmd/templ/lspcmd/proxy/client.go:72 +0x41c
github.com/a-h/templ/lsp/protocol.clientDispatch({0x1013f7c08, 0x14000232c90}, 0x1400003e840, {0x1013fb958, 0x14000232c60}, 0x1400070c3f0, {0x149a7eca0, 0x1400041b920})
/Users/REDACTED/.local/share/mise/installs/go/1.25.2/packages/pkg/mod/github.com/a-h/templ@v0.3.960/lsp/protocol/client.go:102 +0x12d0
github.com/a-h/templ/lsp/protocol.NewClient.ClientHandler.func1({0x1013f7c08, 0x14000232c90}, 0x1400070c3f0, {0x149a7eca0, 0x1400041b920})
/Users/REDACTED/.local/share/mise/installs/go/1.25.2/packages/pkg/mod/github.com/a-h/templ@v0.3.960/lsp/protocol/client.go:36 +0x78
github.com/a-h/templ/lsp/protocol.Handlers.ReplyHandler.func1({0x1013f7c08, 0x14000232c90}, 0x140002fe330, {0x149a7eca0, 0x1400041b920})
/Users/REDACTED/.local/share/mise/installs/go/1.25.2/packages/pkg/mod/github.com/a-h/templ@v0.3.960/lsp/jsonrpc2/handler.go:35 +0xb4
github.com/a-h/templ/lsp/protocol.Handlers.AsyncHandler.func2.2()
/Users/REDACTED/.local/share/mise/installs/go/1.25.2/packages/pkg/mod/github.com/a-h/templ@v0.3.960/lsp/jsonrpc2/handler.go:114 +0x6c
created by github.com/a-h/templ/lsp/protocol.Handlers.AsyncHandler.func2 in goroutine 9
/Users/REDACTED/.local/share/mise/installs/go/1.25.2/packages/pkg/mod/github.com/a-h/templ@v0.3.960/lsp/jsonrpc2/handler.go:112 +0x140
templ info output
❯ templ info
(✓) os [ goos=darwin goarch=arm64 ]
(✓) go [ location=/Users/REDACTED/.local/share/mise/installs/go/1.25.2/bin/go version=go version go1.25.2 darwin/arm64 ]
(✓) gopls [ location=/Users/REDACTED/.local/share/mise/installs/go/1.25.2/bin/gopls version=golang.org/x/tools/gopls v0.20.0 ]
(✓) templ [ location=/Users/REDACTED/.local/share/mise/installs/go/1.25.2/bin/templ version=v0.3.960 ]
Desktop (please complete the following information):
- OS:
macos - templ CLI version (
templ version):v0.3.960 - Go version (
go version):go version go1.25.2 darwin/arm64 goplsversion (gopls version):golang.org/x/tools/gopls v0.20.0nvim --version: NVIM v0.12.0-dev-3320+gff777f9a85-Homebrew
Additional context
Logs hinted at an uninitialized/nil SourceMap struct as this lm, ok := sm.TargetLinesToSource[line] map access was cause of the panic.
While looking for code sections where a SourceMap might be accidentally initialized without calling NewSourceMap(), I stumbled upon this code section intempl/cmd/templ/lspcmd/proxy/server.go:291:
generatorOutput, err := generator.Generate(template, w)
if err != nil {
// It's expected to have some failures while generating code from the template, since
// you are likely to have invalid docs while you're typing.
p.Log.Info("generator failure", slog.Any("error", err))
}
p.Log.Info("setting source map cache contents", slog.String("uri", string(uri)))
p.SourceMapCache.Set(string(uri), generatorOutput.SourceMap)SourceMapCache.Set is called even if the call to generator.Generator() might have errored, causing a nil SourceMap to be set in the cache, which could in turn cause a panic during SourceMap access when it is used from the cache.
I am not certain if this is the actual cause of the panic I experience, either way I assume this should be fixed and I'm willing to provide a PR if you agree. According to the comment it seems to be expected that generator.Generator() might fail here, so an early return like in other sections does seem inappropriate.
- Would it be a viable approach to put the
SourceMapCache.Setcall into anelsebranch instead? - Or should we extend the
SourceMapCacheto no-op duringSetif the provided*SourceMapis nil?