{"record":{"id":"52f099de516ac280","repo":"golang/go","slug":"error-loading-go-work-s-d-path-s-appears-mult","errorCode":null,"errorMessage":"error loading go.work:\n%s:%d: path %s appears multiple times in workspace","messagePattern":"error loading go\\.work:\n(.+?):(.+?): path (.+?) appears multiple times in workspace","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/modload/init.go","lineNumber":819,"sourceCode":"\n// LoadWorkFile parses and checks the go.work file at the given path,\n// and returns the absolute paths of the workspace modules' modroots.\n// It does not modify the global state of the modload package.\nfunc LoadWorkFile(path string) (workFile *modfile.WorkFile, modRoots []string, err error) {\n\tworkDir := filepath.Dir(path)\n\twf, err := ReadWorkFile(path)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tseen := map[string]bool{}\n\tfor _, d := range wf.Use {\n\t\tmodRoot := d.Path\n\t\tif !filepath.IsAbs(modRoot) {\n\t\t\tmodRoot = filepath.Join(workDir, modRoot)\n\t\t}\n\n\t\tif seen[modRoot] {\n\t\t\treturn 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)\n\t\t}\n\t\tseen[modRoot] = true\n\t\tmodRoots = append(modRoots, modRoot)\n\t}\n\n\tfor _, g := range wf.Godebug {\n\t\tif err := CheckGodebug(\"godebug\", g.Key, g.Value); err != nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"error loading go.work:\\n%s:%d: %w\", base.ShortPath(path), g.Syntax.Start.Line, err)\n\t\t}\n\t}\n\n\treturn wf, modRoots, nil\n}\n\n// ReadWorkFile reads and parses the go.work file at the given path.\nfunc ReadWorkFile(path string) (*modfile.WorkFile, error) {\n\tpath = base.ShortPath(path) // use short path in any errors\n\tworkData, err := fsys.ReadFile(path)","sourceCodeStart":801,"sourceCodeEnd":837,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/modload/init.go#L801-L837","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (go.work)\ngo 1.22\nuse (\n    ./svc-a\n    ./svc-a      // line 4: duplicate\n)\n// error: path .../svc-a appears multiple times in workspace\n\n// after\ngo 1.22\nuse (\n    ./svc-a\n)","handlingStrategy":"validation","validationCode":"// Deduplicate go.work 'use' entries by absolute path before relying on it.\ndata, _ := os.ReadFile(\"go.work\")\nwf, _ := modfile.ParseWork(\"go.work\", data, nil)\nseen := map[string]bool{}\nfor _, u := range wf.Use {\n    abs, _ := filepath.Abs(u.Path)\n    if seen[abs] {\n        return fmt.Errorf(\"duplicate use %s\", u.Path)\n    }\n    seen[abs] = true\n}","typeGuard":null,"tryCatchPattern":"out, err := exec.Command(\"go\", \"build\", \"./...\").CombinedOutput()\nif err != nil && bytes.Contains(out, []byte(\"appears multiple times in workspace\")) {\n    // regenerate go.work cleanly\n    if rerr := exec.Command(\"go\", \"work\", \"edit\", \"-fmt\", \"go.work\").Run(); rerr != nil {\n        return rerr\n    }\n    out, err = exec.Command(\"go\", \"build\", \"./...\").CombinedOutput()\n}\nreturn err","preventionTips":["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."],"tags":["go-work","use-directive","duplicate","workspace"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}