{"record":{"id":"7748b8e4596db7a5","repo":"golang/go","slug":"replacement-directory-s-does-not-exist","errorCode":null,"errorMessage":"replacement directory %s does not exist","messagePattern":"replacement directory (.+?) does not exist","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/modload/import.go","lineNumber":809,"sourceCode":"\tif r := Replacement(ld, mod); r.Path != \"\" {\n\t\tif r.Version == \"\" {\n\t\t\tdir = r.Path\n\t\t\tif !filepath.IsAbs(dir) {\n\t\t\t\tdir = filepath.Join(replaceRelativeTo(ld), dir)\n\t\t\t}\n\t\t\t// Ensure that the replacement directory actually exists:\n\t\t\t// dirInModule does not report errors for missing modules,\n\t\t\t// so if we don't report the error now, later failures will be\n\t\t\t// very mysterious.\n\t\t\tif _, err := fsys.Stat(dir); err != nil {\n\t\t\t\t// TODO(bcmills): We should also read dir/go.mod here and check its Go version,\n\t\t\t\t// and return a gover.TooNewError if appropriate.\n\n\t\t\t\tif os.IsNotExist(err) {\n\t\t\t\t\t// Semantically the module version itself “exists” — we just don't\n\t\t\t\t\t// have its source code. Remove the equivalence to os.ErrNotExist,\n\t\t\t\t\t// and make the message more concise while we're at it.\n\t\t\t\t\terr = fmt.Errorf(\"replacement directory %s does not exist\", r.Path)\n\t\t\t\t} else {\n\t\t\t\t\terr = fmt.Errorf(\"replacement directory %s: %w\", r.Path, err)\n\t\t\t\t}\n\t\t\t\treturn dir, true, module.VersionError(mod, err)\n\t\t\t}\n\t\t\treturn dir, true, nil\n\t\t}\n\t\tmod = r\n\t}\n\n\tif mustHaveSums(ld) && !modfetch.HaveSum(ld.Fetcher(), mod) {\n\t\treturn \"\", false, module.VersionError(mod, &sumMissingError{})\n\t}\n\n\tdir, err = ld.Fetcher().Download(ctx, mod)\n\treturn dir, false, err\n}\n","sourceCodeStart":791,"sourceCodeEnd":827,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/modload/import.go#L791-L827","documentation":"A go.mod 'replace' directive points the module at a local filesystem directory, but fsys.Stat reports os.ErrNotExist for that directory. The check exists because dirInModule silently treats missing modules as empty, so without it the later failure would be opaque. The error is wrapped via module.VersionError so it carries the module version identity.","triggerScenarios":"go.mod contains 'replace example.com/foo => ./local/foo' and ./local/foo does not exist on the working directory / module root. Happens during package import resolution / build when that replacement is consulted.","commonSituations":"Checked out a fork branch without the local dir; relative replace path authored on a different OS layout; replace target was gitignored or not yet created; monorepo where the sibling module was not generated/built.","solutions":["Create the missing directory and ensure it has a go.mod with the expected module path.","Fix the replace path in go.mod to point at the correct relative or absolute location.","Remove or comment out the replace directive if the local override is no longer needed.","If the directory should come from another repo/branch, fetch it first or switch to a versioned replace (=> example.com/foo v1.2.3)."],"exampleFix":"// before (go.mod)\nreplace example.com/foo => ./internal/foo   // ./internal/foo absent\n// error: replacement directory ./internal/foo does not exist\n\n// after\nmkdir -p internal/foo\ncat > internal/foo/go.mod <<EOF\nmodule example.com/foo\ngo 1.22\nEOF","handlingStrategy":"validation","validationCode":"// Validate every local replace target exists before building.\ndata, _ := os.ReadFile(\"go.mod\")\nf, _ := modfile.Parse(\"go.mod\", data, nil)\nfor _, r := range f.Replace {\n    if r.New.Version == \"\" { // local directory replace\n        if _, err := os.Stat(r.New.Path); os.IsNotExist(err) {\n            return fmt.Errorf(\"replace target missing: %s\", r.New.Path)\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"out, err := exec.Command(\"go\", \"build\", \"./...\").CombinedOutput()\nif err != nil && bytes.Contains(out, []byte(\"replacement directory\") && bytes.Contains(out, []byte(\"does not exist\"))) {\n    // surface the missing path and stop, rather than opaque downstream failures\n    return fmt.Errorf(\"go.mod replace target missing; fix go.mod: %s\", out)\n}\nreturn err","preventionTips":["Keep local replace targets under the repo root and commit them.","Pre-commit: stat each local replace path and fail fast.","Avoid OS-specific absolute replace paths in shared go.mod files.","Document required sibling checkouts in the project README."],"tags":["replace-directive","local-replace","filesystem","missing-directory"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}