Gopls release v0.24.0 (Oct 2026)
In this release:
Key features are described below.
Gopls now supports v3.18 of the Language Server Protocol.
This release includes a number of improvements to support for Go assembly files, including Hover, DocumentHighlight, References, and “zero configuration” (automatic selection of appropriate build tags).
Configuration changes
The memoryLimit setting allows clients to set a soft memory limit on
the gopls process using
runtime/debug.SetMemoryLimit.
This feature is experimental. It may permit users to trade more CPU
for lower steady state memory usage; but it may cause GC thrashing if
set too low.
The gopls server now enforces
SemanticTokensClientCapabilities
fields: TokenTypes and TokenModifiers. The semantic token types and
modifiers gopls returns are now limited to what these lists contain, so
it’s important that clients fully list their semantic token
capabilities. The gopls UI settings
semanticTokenTypes
and
semanticTokenModifiers
can still be used by users to further restrict these lists.
Gopls’ “zero-configuration” behavior, which causes it to automatically select appropriate OS/ARCH combinations to build the open Go source files, now respects any open Go assembly files too.
Passive features
Gopls now supports the Hover request in Go assembly files: hovering over a symbol reports the signature and doc comment of its Go declaration.
Editing features
Hovering over the case or default keyword
in a type switch reveals any types handled by that case that are
declared in the same package as the switch operand’s interface type.
Hovering over the default case may thus reveal unhandled types
in a switch intended to be exhaustive.
Information is displayed for a non-interface type case
only if it is unreachable due to preceding clauses.
Hovering over a package name definition, reference or import now
renders doc links as links to their definition in code or pkgsite.
e.g. [TestA.FieldOne] in the comment // xyz uses [TestA.FieldOne].
Gopls now supports the textDocument/documentHighlight request in Go
assembly files: all occurrences of the symbol, label, or machine
register under the cursor are highlighted within the enclosing TEXT
function, with definitions classified as writes and references as
reads.
The textDocument/references request in Go assembly files now supports
control labels and symbols that have no corresponding Go declaration.
Completion items now report
labelDetails
to clients that advertise completionItem.labelDetailsSupport: detail
holds the signature or the type of the item, and description holds the
import path that accepting it adds to the file. Only an item that adds
an import has a description, so a client can mark those items.
Analysis features
Gopls is now using staticcheck v0.8.1.
ptrtoerror analyzer
This new analyzer reports inconsistent use of a named type E and its
pointer type *E as an error.
Declaring func (E) Error() string causes both E and *E to
implement error, so a package may inadvertently return E{...} in
one place and &E{...} in another. This is a latent bug: a client
that checks for the error using a type assertion or errors.Is must
choose one of the two types, and the check silently fails whenever the
error was created using the other form.
The analyzer reports three kinds of problem:
- Within the package that declares
E, values of bothEand*Eare converted toerror. The analyzer reports the type declaration and each conversion. - The declaring package consistently uses one form, but another
package converts the other form to
error. The analyzer reports the conversion in the other package and indicates where the declaring package uses the preferred form. - Both
Eand*Eimplementerror, but the declaring package doesn’t convert either one toerror, so the intended form is unclear. The analyzer offers two alternative fixes that declare the intended form explicitly, eithervar _ error = *new(E)orvar _ error = (*E)(nil).
slicesclip modernizer
The new slicesclip modernizer suggests replacing a full slice
expression of the form x[:len(x):len(x)], which clips the capacity
of a slice to its length, with the simpler and more readable
slices.Clip(x), added in Go 1.21.
importcomment modernizer
The new importcomment modernizer removes obsolete comments
specifying the canonical import path of a package, such as
package foo // import "example.com/foo". The go command enforced
these comments only in GOPATH mode; in module mode they are ignored.
reflecttypeassert modernizer
The new reflecttypeassert modernizer suggests replacing a two-valued
type assertion on the result of reflect.Value.Interface, such as
x, ok := v.Interface().(T), with x, ok := reflect.TypeAssert[T](v),
added in Go 1.25, which avoids allocating an intermediate interface value.
No fix is offered for single-valued assertions, which panic on failure
whereas reflect.TypeAssert does not.
stringintconv updates for Go 1.28
Go 1.28 rejects conversions string(x) where x is an integer other
than byte or rune (#3939). The
stringintconv analyzer’s first suggested fix now preserves the
existing behavior exactly, using string(rune(x)), or
fmt.Sprintf("%c", x) for types wider than 32 bits, since truncation
to a rune could make an invalid code point valid; the second fix,
fmt.Sprintf("%d", x), formats
the number as a decimal. The same two fixes are now offered as quick
fixes for the type error reported in files using Go 1.28 or later.
Code transformation features
“Implement interface” supports generic interfaces
The interactive “Add methods to implement an interface…” code action now
supports generic interfaces. When the selected interface has type parameters,
gopls prompts for a type argument for each type parameter and generates
method stubs with the instantiated method signatures.
Demo of interactive dialog support: “Slay the dragon”
The LSP standard currently provides no way for the server to ask the client a question such as “where should I move this function?” or “should I proceed with this ambiguous operation?”.
In conjunction with the Dart IDE team, the Go team has designed and implemented an extension to the Language Server Protocol to enable interactive dialogs. We are currently trying to get it adopted by the LSP standard and implemented in various popular client editors, and plan to use it for future interactive features.
As a demonstration of the feature and a test case for client
implementations, gopls now offers a “Slay the dragon” code action when
you select a package-level variable named dragonSlayer.
A dragon has been spotted near your code.
What happens next is up to you!
The source files for this documentation can be found beneath golang.org/x/tools/gopls/doc.