golang/go · error

valid modes are "set", "count", or "atomic"

Error message

valid modes are "set", "count", or "atomic"

What it means

Thrown by coverModeFlag.Set in cmd/go/internal/work when -covermode is given a value other than "set", "count", "atomic", or empty. -covermode controls how coverage is recorded per basic block: set (boolean), count (integer), atomic (integer with sync for racing tests). Any other spelling is rejected.

Source

Thrown at src/cmd/go/internal/work/build.go:946

func (f coverFlag) Set(value string) error {
	if err := f.V.Set(value); err != nil {
		return err
	}
	cfg.BuildCover = true
	return nil
}

type coverModeFlag string

func (f coverModeFlag) String() string { return string(f) }
func (f *coverModeFlag) Set(value string) error {
	switch value {
	case "", "set", "count", "atomic":
		*f = coverModeFlag(value)
		cfg.BuildCoverMode = value
		return nil
	default:
		return errors.New(`valid modes are "set", "count", or "atomic"`)
	}
}

// A commaListFlag is a flag.Value representing a comma-separated list.
type commaListFlag struct{ Vals *[]string }

func (f commaListFlag) String() string { return strings.Join(*f.Vals, ",") }

func (f commaListFlag) Set(value string) error {
	if value == "" {
		*f.Vals = nil
	} else {
		*f.Vals = strings.Split(value, ",")
	}
	return nil
}

// A stringFlag is a flag.Value representing a single string.

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Use one of: set, count, atomic (or omit the flag; go picks a sensible default based on -race).
  2. If you need branch/condition coverage, that is not supported by the Go coverage tool — use a separate tool or the new GOCOVERDIR-based coverage collection.
  3. Validate the value against {"set","count","atomic"} in your CI script before invoking go test.
  4. Check for shell aliases or Makefile variables that mangle the flag value.

Example fix

# before
go test -covermode=branch ./...
# after
go test -covermode=count ./...
Defensive patterns

Strategy: validation

Validate before calling

var validCoverModes = map[string]bool{"set": true, "count": true, "atomic": true}
if mode != "" && !validCoverModes[mode] {
    return fmt.Errorf("-covermode %q invalid; want set|count|atomic", mode)
}

Type guard

func isValidCoverMode(s string) bool {
    return s == "" || s == "set" || s == "count" || s == "atomic"
}

Prevention

When it happens

Trigger: Running `go test -covermode=branch`, `-covermode=line`, `-covermode=on/off`, or a typo like `-covermode=atmoic`. CI configs that pass an unsupported mode name. Documentation that conflates -covermode with -coverpkg.

Common situations: Developers familiar with gcov/lcov mode names expecting "branch" or "line". Auto-generated coverage matrices that interpolate a variable into -covermode. Typos.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/6a9c6b4435e58e90. Report an issue: GitHub.