{"record":{"id":"83d4503ba0a981bd","repo":"golang/go","slug":"not-a-directory","errorCode":null,"errorMessage":"not a directory","messagePattern":"not a directory","errorType":"exception","errorClass":"DownloadDirPartialError","httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/modfetch/cache.go","lineNumber":103,"sourceCode":"\tif !gover.ModIsValid(m.Path, m.Version) {\n\t\treturn \"\", fmt.Errorf(\"non-semver module version %q\", m.Version)\n\t}\n\tif module.CanonicalVersion(m.Version) != m.Version {\n\t\treturn \"\", fmt.Errorf(\"non-canonical module version %q\", m.Version)\n\t}\n\tencVer, err := module.EscapeVersion(m.Version)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// Check whether the directory itself exists.\n\tdir := filepath.Join(cfg.GOMODCACHE, enc+\"@\"+encVer)\n\tif fi, err := os.Stat(dir); os.IsNotExist(err) {\n\t\treturn dir, err\n\t} else if err != nil {\n\t\treturn dir, &DownloadDirPartialError{dir, err}\n\t} else if !fi.IsDir() {\n\t\treturn dir, &DownloadDirPartialError{dir, errors.New(\"not a directory\")}\n\t}\n\n\t// Check if a .partial file exists. This is created at the beginning of\n\t// a download and removed after the zip is extracted.\n\tpartialPath, err := CachePath(ctx, m, \"partial\")\n\tif err != nil {\n\t\treturn dir, err\n\t}\n\tif _, err := os.Stat(partialPath); err == nil {\n\t\treturn dir, &DownloadDirPartialError{dir, errors.New(\"not completely extracted\")}\n\t} else if !os.IsNotExist(err) {\n\t\treturn dir, err\n\t}\n\n\t// Special case: ziphash is not required for the golang.org/fips140 module,\n\t// because it is unpacked from a file in GOROOT, not downloaded.\n\t// We've already checked that it's not a partial unpacking, so we're happy.\n\tif m.Path == \"golang.org/fips140\" {","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/modfetch/cache.go#L85-L121","documentation":"DownloadDir expects the cached module path GOMODCACHE/<enc>@<encVer> to be a directory. os.Stat returns an entry at that path whose IsDir() is false (a regular file), so the cache is treated as partially populated and a DownloadDirPartialError (equivalent to fs.ErrNotExist) is returned.","triggerScenarios":"The path GOMODCACHE/<enc>@<encVer> exists but is a file rather than a directory, so DownloadDir refuses to return it.","commonSituations":"Corrupted module cache from a crashed or interrupted extraction; manual tampering inside GOMODCACHE; restoring GOMODCACHE from a bad backup that flattened directories; partial copy of the cache between machines.","solutions":["Run `go clean -modcache` to wipe and re-download the cache cleanly.","Delete just the offending entry (`rm -rf GOMODCACHE/<enc>@<encVer>`) and run `go mod download` again.","Confirm GOMODCACHE points to a writable directory you control and treat it as read-only afterwards."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Before relying on a cached module dir, verify it is a directory:\n//   fi, err := os.Stat(dir)\n//   if err == nil && !fi.IsDir() { /* clean and re-download */ }","typeGuard":null,"tryCatchPattern":"// On *modfetch.DownloadDirPartialError (which wraps fs.ErrNotExist),\n// run `go clean -modcache` (or remove the entry) and retry the build.","preventionTips":["Treat GOMODCACHE as read-only; do not manually create or replace entries.","Run `go clean -modcache` when the cache is suspected corrupt."],"tags":["go","modules","cache","corruption"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}