---
title: "Gopls release v0.22.0 (May 2026)"
---

In this release:

- commits: https://go.googlesource.com/tools/+log/refs/heads/gopls-release-branch.0.21..refs/heads/gopls-release-branch.0.22
- issues closed: https://github.com/golang/go/milestone/415?closed=1 (plus
  a number of modernizer fixes in the [go1.26 milestone](https://github.com/golang/go/milestone/408?closed=1)).

Key features are described below.
Much of the work of this, as usual, consists of numerous small bug fixes.

We are pleased to report that crash stability has improved so much in
recent years that the fraction of gopls telemetry reports clearly due
to hardware failure is significant and growing.

### Interactive code transformations
<!-- golang/go#76331 -->
This release includes support for a non-standard LSP feature that
allows code actions to have [interactive dialogs](https://go.dev/issue/76331).
We expect this to enable all kinds of new features, such as analyzers
that prompt for additional preferences or intent, or code
transformations that ask for advice on how to resolve ambiguities.

This release includes three interactive code actions:
- **Add tags to struct fields**: Prompts the user for the tags to add and
  the casing transformation rule (e.g., `camelCase`, `snake_case`).
- **Remove tags from struct fields**: Prompts the user for the tags to remove.
- **Implement interface**: A new code action that adds method stubs to a type
  to implement a specified interface
  (see [golang/vscode-go#1547](https://github.com/golang/vscode-go/issues/1547)).

Dialog support is a non-standard feature of LSP.
It is currently supported only by `gopls` and requires a language
client (such as VS Code) that supports the proposed protocol.
We plan to work with the broader LSP community to develop other LSP
clients (editors) and servers to refine the design and support dialogs
as a standard part of the protocol.

## Changes to module requirements trigger vulnerability scanning

Gopls now detects changes in the go.mod requirements.
The first time gopls sees a new configuration, for example after a
dependency is upgraded, it will prompt to run [vulnerability
scanning](https://go.dev/blog/govulncheck).

If you prefer to avoid interactive prompts, opt for "always" or
"never" and your choice will be saved persistently in the user's
configuration directory (beneath `os.UserConfigDir`).

The set of available code lenses now includes `run_govulncheck` by default.

## Configuration changes

- The default value for the `vulncheck` setting is now `"Prompt"` (see above).
- The `fieldassignment` analyzer is back by popular demand, though still off by default.
- The experimental `renameMovesSubpackages` setting determines whether
  a package-rename operation should also move subdirectories.
- The `importsSource` setting is deprecated and will be removed in the next release.
- The `-port=int` debugging flag (redundant with `-listen`) has been removed.
- The `-listen=address` flag now rejects an implicit host (e.g. `:0`).
  You must explicitly specify a host such as `0.0.0.0` or (preferably) `localhost`.

## Navigation features
<!-- golang/go#75810 -->

## Navigation features

- In a go.mod file, requesting References while hovering over the name of
  a module in a `require` declaration will report all the imports of
  that module in the module defined by the go.mod file.
  <!-- golang/go#75810 -->

## Analysis features

### `atomictypes` analyzer
<!-- golang/go#77352 -->
The new `atomictypes` analyzer suggests replacing the primitive `sync/atomic` functions with
the strongly typed atomic wrapper types introduced in Go1.19 such as `atomic.Int32`.
The analyzer's fixes change declarations like `var x int32` to `var x
atomic.Int32` and update corresponding call sites from
`atomic.AddInt32(&x, 1)` to method calls like `x.Add(1)`.

### `embedlit` modernizer
<!-- golang/go#77965 -->
The new `embedlit` modernizer suggests removing embedded field type specifiers
from composite literals when they are redundant under the rules of Go 1.27,
which introduces the ability to directly initialize fields promoted from
embedded struct types without a nested literal.

### `fieldassignment` analyzer
<!-- golang/go#76237 -->
The fieldassignment analyzer, which reports diagnostics about memory layout and
was disabled in v0.17.0, has been restored. It is disabled by default.
(Hovering over the declaration of a struct type or its individual fields
continues to reveal its size/class/offset information.)

### `scannererr` analyzer
<!-- golang/go#17747 -->
The scannererr analyzer reports failure to call the Err method when
calling the Scan method of bufio.Scanner in a loop.

### `writestring` analyzer
<!-- golang/go#77369 -->
The new writestring analyzer detects inefficient string concatenation in uses of WriteString,
of the form WriteString(a+b), and offers to replace them with WriteString(a); WriteString(b).

### `waitgroup` modernizer renamed to `waitgroupgo`
<!-- golang/go#77560 -->
Previously there were two analyzers named `waitgroup`: an analyzer that checks
for misuses of `sync.WaitGroup`, and a modernizer that simplifies goroutine
management with `sync.WaitGroup`. We have renamed the modernizer to `waitgroupgo`.

### `stringscut` modernizer now handles `Split` and `SplitN`
The existing `stringscut` modernizer now replaces calls such as
`strings.Split(s, ":")[0]` or `strings.SplitN(s, ":", 2)[0]` with Go
1.18's `strings.Cut(s, ":")`, which is more efficient since it doesn't
need to allocate a short-lived array.

### `yield` analyzer improved precision
The `yield` analyzer, which detects problems in iterators that fail to
stop once `yield()` returns false, has been rewritten as a non-sparse
Killdall-style monotone dataflow analysis, improving its precision.

## Server-side file watching

Gopls introduces an experimental server-side file watching mechanism to monitor file system events directly. This feature supplements standard LSP file change notifications in environments or editor clients where client-side events may be unreliable or dropped.

This feature is configured via the internal setting `fileWatcher`, which supports three strategies:
- `"off"` (default): the client is solely responsible for change notification
- `"poll"`: the server periodically scans workspace directories, using optimizations similar to `git status`
- `"fsnotify"`: the server uses kernel support for file-change notification. This strategy is system dependent and may need to open many directories to watch a large workspace, risking [file descriptor exhaustion](https://github.com/fsnotify/fsnotify#kqueue-macos-all-bsd-systems)
