golang/go · error

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

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.

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)

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.