# Why go-modern-guidelines Requires Go 1.25+ and How It Handles Older Toolchains

> Discover why go-modern-guidelines needs Go 1.25+ and how it manages older toolchains. Learn about automatic downloads for seamless upgrades.

- Repository: [JetBrains/go-modern-guidelines](https://github.com/jetbrains/go-modern-guidelines)
- Tags: internals
- Published: 2026-09-04

---

**The go-modern-guidelines CLI requires Go 1.25+ to safely reference modern standard library features like `slices.Contains` and `cmp.Or`, and automatically downloads compatible toolchains via `GOTOOLCHAIN=auto` when the local installation is older.**

The JetBrains go-modern-guidelines tool enforces contemporary Go coding standards by leveraging features introduced across Go 1.21 through 1.27. To guarantee compatibility with these modern APIs, the CLI declares a minimum Go 1.25 toolchain requirement in its source code. Understanding how the tool resolves versions and handles legacy installations ensures smooth operation across diverse development environments.

## Understanding the Go 1.25+ Toolchain Requirement

### Modern Standard Library Dependencies

The CLI analyzes code against contemporary Go idioms that rely on standard library additions introduced incrementally from Go 1.21 onward. According to the source analysis, these include **slices.Contains**, **cmp.Or**, and **errors.AsType[T]**, among others. The analyzer must be able to reference these APIs to validate code against modern guidelines.

### The 1.25 Minimum Threshold

While modern features began appearing in Go 1.21, the project declares **Go 1.25** as the minimum toolchain in [`internal/goversion/goversion.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/goversion/goversion.go). This version guarantees full support for the complete set of std-lib additions the guidelines rely on, ensuring the analyzer can safely reference these APIs without runtime errors on older installations.

## How the CLI Resolves Go Versions

The version resolution logic lives in [`internal/goversion/goversion.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/goversion/goversion.go), which implements a cascading detection strategy called from [`internal/cli/cli.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/cli/cli.go).

### Explicit Version Flags

Users can bypass automatic detection entirely by passing the `--go-version` flag or pointing to a `go.mod` or `go.work` file. The parser normalizes these inputs within lines 18-27 of [`goversion.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/goversion.go):

```go
// Lines 18-27: Parses --go-version or go.mod/go.work directives

```

### Automatic Local Toolchain Detection

When no explicit version is provided, the CLI executes `go env GOVERSION` to query the local installation (lines 62-71 of [`goversion.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/goversion.go)). This detects the actively installed toolchain version for comparison against the 1.25 minimum threshold.

## Behavior with Older Go Versions

The CLI's behavior when encountering Go versions below 1.25 depends entirely on the `GOTOOLCHAIN` environment variable configuration.

### Automatic Toolchain Switching (GOTOOLCHAIN=auto)

By default, Go enables automatic toolchain switching (`GOTOOLCHAIN=auto`). When the CLI detects a local toolchain older than 1.25, the Go runtime automatically downloads and installs a compatible 1.25+ version on first invocation. This allows the program to execute successfully even on machines with legacy Go installations, as documented in [`README.md`](https://github.com/JetBrains/go-modern-guidelines/blob/main/README.md) lines 31-32.

### Manual Override with --go-version

When automatic switching is unavailable or undesirable, users can specify an exact version manually to force specific Go semantics:

```bash
go-modern-guidelines --go-version=1.24 list

```

### Error Handling When Switching is Disabled

If `GOTOOLCHAIN` is set to `local` or otherwise disabled, and the local installation is below 1.25, the `resolveGoToolVersion` function fails with a clear directive:

```text
cannot determine the Go version from <source>. Pass --go-version explicitly, for example --go-version=1.24

```

This error originates in the `goversion` package and requires manual version specification or toolchain upgrade.

## Practical Execution Scenarios

Demonstrating the three primary execution patterns:

```bash

# Scenario 1: Modern toolchain installed (≥1.25)

go-modern-guidelines list

# Uses existing toolchain without additional downloads

# Scenario 2: Force specific version (useful for testing or older toolchains)

go-modern-guidelines --go-version=1.24 list

# Uses Go 1.24 semantics even if local Go is newer

# Scenario 3: Disabled toolchain switching on old installation

GOTOOLCHAIN=local go-modern-guidelines list

# Error: cannot determine the Go version from local Go toolchain...

```

## Summary

- The CLI requires Go 1.25+ to safely reference modern standard library features introduced between Go 1.21 and 1.27.
- Version resolution occurs in [`internal/goversion/goversion.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/goversion/goversion.go) via explicit flags (lines 18-27) or `go env GOVERSION` detection (lines 62-71).
- `GOTOOLCHAIN=auto` (default) enables automatic downloading of compatible toolchains when local versions are insufficient.
- Disabled automatic switching triggers a clear error message directing users to specify `--go-version` manually via the `resolveGoToolVersion` function.

## Frequently Asked Questions

### What happens if I only have Go 1.22 installed?

If `GOTOOLCHAIN` is set to `auto` (the default), the Go runtime automatically downloads Go 1.25+ the first time you run the CLI, then executes normally. If automatic switching is disabled, you must either upgrade your local installation or use the `--go-version` flag to specify a compatible version explicitly.

### Can I force the CLI to use a specific Go version even if I have a newer one installed?

Yes. Use the `--go-version` flag (for example, `--go-version=1.24`) to override automatic detection. This directs the analyzer to use Go 1.24 semantics regardless of your local toolchain version, as implemented in the flag parsing logic within [`internal/cli/cli.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/cli/cli.go).

### Why is Go 1.25 the minimum instead of Go 1.21?

While many modern features appeared in Go 1.21, the CLI relies on standard library additions introduced through Go 1.27. Version 1.25 represents the minimum toolchain that guarantees complete API support for all guidelines functionality, ensuring the analyzer can reference features like `errors.AsType[T]` without compatibility issues when validating code.

### Where does the version detection logic live?

The resolution logic is implemented in [`internal/goversion/goversion.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/goversion/goversion.go), specifically within the functions handling lines 18-27 (explicit version parsing) and lines 62-71 (local toolchain detection). The error handling for insufficient versions resides in the `resolveGoToolVersion` function within the same file.