go mod tidy error message: "but go 1.16 would select"

Issue

When I run go mod tidy a few packages show an error

> go mod tidy

github.com/myrepo/myproj imports
    go.k6.io/k6 imports
    go.k6.io/k6/cmd imports
    github.com/fatih/color loaded from github.com/fatih/color@v1.12.0,
    but go 1.16 would select v1.13.0

To upgrade to the versions selected by go 1.16:
    go mod tidy -go=1.16 && go mod tidy -go=1.17
If reproducibility with go 1.16 is not needed:
    go mod tidy -compat=1.17
For other options, see:
    https://golang.org/doc/modules/pruning

I have go 1.17.9 installed. What’s the meaning of the error and why is it being triggered?

Solution

This error is related to module graph pruning introduced in Go 1.17.

With Go 1.16, the module graph for Minimal Version Selection used to include the full module graph, whereas with 1.17 the graph includes only up to transitive dependencies (with some exceptions, see the link above).

Now to understand what triggers the error, you might want to look at the Go 1.17 release notes:

By default, go mod tidy verifies that the selected versions of dependencies relevant to the main module are the same versions that would be used by the prior Go release (Go 1.16 for a module that specifies go 1.17) […]

So when you run go mod tidy, it reports that Go 1.16 "would select" a version of a transitive dependency (github.com/fatih/color) that is different from the one that the pruned graph of Go 1.17 would.

This is relevant for build reproducibility, because go.sum contains the checksums for the current Go version specified in go.mod and the previous one. In case of Go 1.17 and Go 1.16 where the module graph effectively can change, go.sum would be inconsistent.

The error message suggests two fixes.

  1. go mod tidy -go=1.16 && go mod tidy -go=1.17 — this selects the dependency versions as Go 1.16 and then as Go 1.17

  2. go mod tidy -compat=1.17 — this simply removes the Go 1.16 checksums (hence the tip "reproducibility with go 1.16 is not needed").

The error should not present itself anymore after you upgrade to Go 1.18, because then the module graph will be loaded the same as in Go 1.17.

Answered By – blackgreen

Answer Checked By – Pedro (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.