golang/go · error

cannot load module listed in go.work file

Error message

cannot load module %s listed in go.work file: %w

What it means

In workspace mode, loading one of the go.mod files referenced by go.work 'use' directives failed. The original error (potentially a TooNewError that was NOT rewritten because the command is not a 'work ' subcommand, or some other read/parse failure) is wrapped with the short path of the module directory. Errs are collected so multiple broken members can be reported together.

Solutions

  1. Open the reported module directory and fix/restore its go.mod.
  2. If the member no longer exists, drop it: 'go work edit -dropuse=./X'.
  3. For a TooNewError root cause, upgrade the toolchain (GOTOOLCHAIN=auto) or lower the member's go directive.
  4. Re-run; additional member errors may surface one batch at a time.

Example fix

// before
$ go build ./...
// cannot load module ./svc-b listed in go.work: reading svc-b/go.mod: open: no such file

// after
$ go work edit -dropuse=./svc-b     // svc-b was removed
$ go build ./...
Defensive patterns

Strategy: validation

Validate before calling

// Verify every go.work 'use' member has a loadable go.mod.
data, _ := os.ReadFile("go.work")
wf, _ := modfile.ParseWork("go.work", data, nil)
for _, u := range wf.Use {
    gomod := filepath.Join(u.Path, "go.mod")
    if _, err := os.Stat(gomod); err != nil {
        return fmt.Errorf("workspace member %s missing go.mod: %w", u.Path, err)
    }
    if _, err := modfile.Parse(gomod, mustReadFile(gomod), nil); err != nil {
        return fmt.Errorf("workspace member %s go.mod invalid: %w", u.Path, err)
    }
}

Try / catch

out, err := exec.Command("go", "build", "./...").CombinedOutput()
if err != nil && bytes.Contains(out, []byte("cannot load module") && bytes.Contains(out, "listed in go.work")) {
    // drop the stale member, then retry
    member := extractMemberFromError(out) // your helper
    _ = exec.Command("go", "work", "edit", "-dropuse="+member).Run()
    out, err = exec.Command("go", "build", "./...").CombinedOutput()
}
return err

Prevention

When it happens

Trigger: A go.work 'use ./X' points at a directory whose go.mod is missing, unreadable, unparseable, or declares a go version too new for the toolchain AND the current command is not 'go work ...'. ReadModFile returns err, the workspace branch wraps it.

Common situations: A workspace member submodule was deleted/moved but not dropped from go.work; a member go.mod has merge-conflict artifacts; toolchain too old for a member's go directive; relative 'use' path broken after a directory rename.

Related errors


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

Appendix: source

Thrown at src/cmd/go/internal/modload/init.go:1043

	var modFiles []*modfile.File
	var mainModules []module.Version
	var indices []*modFileIndex
	var errs []error
	for _, modroot := range ld.modRoots {
		gomod := modFilePath(modroot)
		var fixed bool
		data, f, err := ReadModFile(gomod, fixVersion(ld, ctx, &fixed))
		if err != nil {
			if ld.inWorkspaceMode() {
				if tooNew, ok := err.(*gover.TooNewError); ok && !strings.HasPrefix(cfg.CmdName, "work ") {
					// Switching to a newer toolchain won't help - the go.work has the wrong version.
					// Report this more specific error, unless we are a command like 'go work use'
					// or 'go work sync', which will fix the problem after the caller sees the TooNewError
					// and switches to a newer toolchain.
					err = errWorkTooOld(gomod, workFile, tooNew.GoVersion)
				} else {
					err = fmt.Errorf("cannot load module %s listed in go.work file: %w",
						base.ShortPath(filepath.Dir(gomod)), base.ShortPathError(err))
				}
			}
			errs = append(errs, err)
			continue
		}
		if ld.inWorkspaceMode() && !strings.HasPrefix(cfg.CmdName, "work ") {
			// Refuse to use workspace if its go version is too old.
			// Disable this check if we are a workspace command like work use or work sync,
			// which will fix the problem.
			mv := gover.FromGoMod(f)
			wv := gover.FromGoWork(workFile)
			if gover.Compare(mv, wv) > 0 && gover.Compare(mv, gover.GoStrictVersion) >= 0 {
				errs = append(errs, errWorkTooOld(gomod, workFile, mv))
				continue
			}
		}

View on GitHub (pinned to b6b368adc5)