golang/go · error
error loading go.work: %s:%d: path %s appears multiple times
Error message
error loading go.work: %s:%d: path %s appears multiple times in workspace
What it means
Loading a go.work file found the same module root path listed in two or more 'use' directives. The loader de-duplicates by absolute modRoot (relative paths are joined to workDir first), and the second occurrence is rejected. Line number of the offending 'use' directive is included.
Source
Thrown at src/cmd/go/internal/modload/init.go:819
// LoadWorkFile parses and checks the go.work file at the given path,
// and returns the absolute paths of the workspace modules' modroots.
// It does not modify the global state of the modload package.
func LoadWorkFile(path string) (workFile *modfile.WorkFile, modRoots []string, err error) {
workDir := filepath.Dir(path)
wf, err := ReadWorkFile(path)
if err != nil {
return nil, nil, err
}
seen := map[string]bool{}
for _, d := range wf.Use {
modRoot := d.Path
if !filepath.IsAbs(modRoot) {
modRoot = filepath.Join(workDir, modRoot)
}
if seen[modRoot] {
return nil, nil, fmt.Errorf("error loading go.work:\n%s:%d: path %s appears multiple times in workspace", base.ShortPath(path), d.Syntax.Start.Line, modRoot)
}
seen[modRoot] = true
modRoots = append(modRoots, modRoot)
}
for _, g := range wf.Godebug {
if err := CheckGodebug("godebug", g.Key, g.Value); err != nil {
return nil, nil, fmt.Errorf("error loading go.work:\n%s:%d: %w", base.ShortPath(path), g.Syntax.Start.Line, err)
}
}
return wf, modRoots, nil
}
// ReadWorkFile reads and parses the go.work file at the given path.
func ReadWorkFile(path string) (*modfile.WorkFile, error) {
path = base.ShortPath(path) // use short path in any errors
workData, err := fsys.ReadFile(path)View on GitHub (pinned to b6b368adc5)
Solutions
- Edit go.work and remove the duplicate 'use' line at the reported line number.
- Run 'go work edit -dropuse=./duppath go.work' to drop one entry.
- Rebuild the file with 'go work use .' letting the tool regenerate a clean, deduplicated go.work.
- Verify the two paths really resolve to the same directory (absolutize them) before deleting.
Example fix
// before (go.work)
go 1.22
use (
./svc-a
./svc-a // line 4: duplicate
)
// error: path .../svc-a appears multiple times in workspace
// after
go 1.22
use (
./svc-a
) Defensive patterns
Strategy: validation
Validate before calling
// Deduplicate go.work 'use' entries by absolute path before relying on it.
data, _ := os.ReadFile("go.work")
wf, _ := modfile.ParseWork("go.work", data, nil)
seen := map[string]bool{}
for _, u := range wf.Use {
abs, _ := filepath.Abs(u.Path)
if seen[abs] {
return fmt.Errorf("duplicate use %s", u.Path)
}
seen[abs] = true
} Try / catch
out, err := exec.Command("go", "build", "./...").CombinedOutput()
if err != nil && bytes.Contains(out, []byte("appears multiple times in workspace")) {
// regenerate go.work cleanly
if rerr := exec.Command("go", "work", "edit", "-fmt", "go.work").Run(); rerr != nil {
return rerr
}
out, err = exec.Command("go", "build", "./...").CombinedOutput()
}
return err Prevention
- Let 'go work use' manage go.work; avoid hand-adding 'use' lines.
- Lint go.work for duplicate use entries in pre-commit.
- Normalize relative paths to absolute before comparing.
- Resolve merge conflicts in go.work fully before building.
When it happens
Trigger: go.work contains duplicate 'use' entries, e.g. 'use ./a' and 'use ./a' or 'use ./a' plus 'use ../repo/a' that resolve to the same absolute path. Surfaces during any workspace-aware command.
Common situations: Hand-edited go.work; 'go work use ./a' run twice without dedup awareness (the tool normally dedups, but manual edits or merges reintroduce duplicates); path normalization differences between relative entries.
Related errors
- cannot load module %s listed in go.work file: %w
- error loading go.work: %s:%d: %w
- module %s listed in go.work file requires go >= %s, but go.w
- %s is contained in a module that is not one of the workspace
- %s outside modules listed in go.work or their selected depen
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/52f099de516ac280.
Report an issue: GitHub.