Skip to content

x/tools/gopls: poor / invalid import suggestions #76310

@seankhliao

Description

@seankhliao

gopls version

Build info
----------
golang.org/x/tools/gopls v0.0.0-20251114214326-41c94d8a4cc2
    golang.org/x/tools/gopls@v0.0.0-20251114214326-41c94d8a4cc2
    github.com/BurntSushi/toml@v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
    github.com/fatih/camelcase@v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
    github.com/fatih/gomodifytags@v1.17.1-0.20250423142747-f3939df9aa3c h1:dDSgAjoOMp8da3egfz0t2S+t8RGOpEmEXZubcGuc0Bg=
    github.com/fatih/structtag@v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
    github.com/fsnotify/fsnotify@v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
    github.com/google/go-cmp@v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
    github.com/google/jsonschema-go@v0.3.0 h1:6AH2TxVNtk3IlvkkhjrtbUc4S8AvO0Xii0DxIygDg+Q=
    github.com/modelcontextprotocol/go-sdk@v0.8.0 h1:jdsBtGzBLY287WKSIjYovOXAqtJkP+HtFQFKrZd4a6c=
    github.com/yosida95/uritemplate/v3@v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
    golang.org/x/exp/typeparams@v0.0.0-20251023183803-a4bb9ffd2546 h1:HDjDiATsGqvuqvkDvgJjD1IgPrVekcSXVVE21JwvzGE=
    golang.org/x/mod@v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
    golang.org/x/sync@v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
    golang.org/x/sys@v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
    golang.org/x/telemetry@v0.0.0-20251111182119-bc8e575c7b54 h1:E2/AqCUMZGgd73TQkxUMcMla25GB9i/5HOdLr+uH7Vo=
    golang.org/x/text@v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
    golang.org/x/tools@v0.38.0 => ../
    golang.org/x/vuln@v1.1.4 h1:Ju8QsuyhX3Hk8ma3CesTbO8vfJD9EvUBgHvkxHBzj0I=
    honnef.co/go/tools@v0.7.0-0.dev.0.20251022135355-8273271481d0 h1:5SXjd4ET5dYijLaf0O3aOenC0Z4ZafIWSpjUzsQaNho=
    mvdan.cc/gofumpt@v0.8.0 h1:nZUCeC2ViFaerTcYKstMmfysj6uhQrA2vJe+2vwGU6k=
    mvdan.cc/xurls/v2@v2.6.0 h1:3NTZpeTxYVWNSokW3MKeyVkz/j7uYXYiMtXRUfmjbgI=
go: go1.26-devel_7995751d3a 2025-11-07 14:16:34 -0800 X:jsonv2

go env

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='0'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v3'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/user/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/user/.config/go/env'
GOEXE=''
GOEXPERIMENT='jsonv2'
GOFIPS140='off'
GOFLAGS='-trimpath "-ldflags=-s -w" -vet=all'
GOGCCFLAGS='-fPIC -m64 -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build134216039=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/home/user/tmp/testrepo1304/go.mod'
GOMODCACHE='/home/user/.data/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/user/.data/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/user/sdk/gotip'
GOSUMDB='sum.golang.org'
GOTELEMETRY='on'
GOTELEMETRYDIR='/home/user/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='path'
GOTOOLDIR='/home/user/sdk/gotip/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.26-devel_7995751d3a 2025-11-07 14:16:34 -0800'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

go.mod:

module go.seankhliao.com/testrepo1304

go 1.26

main.go:

package main

func main() {
	uuid.New
}

Have gopls complete imports

$ for i in {1..10}; do gopls imports main.go ; done
package main

import "github.com/pborman/uuid"

func main() {
	uuid.New
}
package main

import "github.com/google/uuid"

func main() {
	uuid.New
}
package main

import "github.com/!azure/azure-sdk-for-go/sdk/internal/uuid"

func main() {
	uuid.New
}
package main

import "github.com/!azure/azure-sdk-for-go/sdk/internal/uuid"

func main() {
	uuid.New
}
package main

import "github.com/pborman/uuid"

func main() {
	uuid.New
}
package main

import "github.com/!azure/azure-sdk-for-go/sdk/internal/uuid"

func main() {
	uuid.New
}
package main

import "github.com/google/uuid"

func main() {
	uuid.New
}
package main

import "github.com/pborman/uuid"

func main() {
	uuid.New
}
package main

import "github.com/!azure/azure-sdk-for-go/sdk/internal/uuid"

func main() {
	uuid.New
}
package main

import "github.com/!azure/azure-sdk-for-go/sdk/internal/uuid"

func main() {
	uuid.New
}

What did you see happen?

Gopls selected different uuid package, one of which was unusable.
The azure package was an internal package of a different module,
and had an invalid import path (!a instead of A).

in the editor, the azure import is always ranked first in completion suggestions

What did you expect to see?

github.com/google/uuid to be selected as the import.

Reproducing this appears to depend on the state of the module cache.
If I set GOMODCACHE to an empty directory, I get 0 suggestions.

Editor and settings

neovim.

vim.lsp.config("gopls", {
    -- https://github.com/golang/tools/tree/master/gopls
    cmd = { "gopls" },
    filetypes = { "go", "gomod", "gowork", "gotmpl" },
    root_markers = { "go.mod", "go.sum", "go.work", ".git" },
    settings = {
        gopls = {
            gofumpt = true,
            staticcheck = true,
            templateExtensions = { "gotmpl" },
            vulncheck = "Imports",
            analyses = {
                shadow = true,
            },
        },
    },
    on_init = function(client)
        local path = client.workspace_folders[1].name
        if path:find("/sdk/") then
            -- disable gofumpt when working on Go project repos
            client.config.settings.gopls.gofumpt = false
        end
    end,
})
vim.lsp.enable("gopls")

Logs

No logs from cli invocation

log file from using organizeImports in editor

gopls.log

Metadata

Metadata

Assignees

Labels

BugReportIssues describing a possible bug in the Go implementation.ToolsThis label describes issues relating to any tools in the x/tools repository.goplsIssues related to the Go language server, gopls.

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions