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 both E and *E are converted to error. 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 E and *E implement error, but the declaring package doesn’t convert either one to error, so the intended form is unclear. The analyzer offers two alternative fixes that declare the intended form explicitly, either var _ error = *new(E) or var _ 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.