{"record":{"id":"3e259487d3f96fb5","repo":"golang/go","slug":"overlay-maps-to-directory","errorCode":null,"errorMessage":"overlay maps to directory","messagePattern":"overlay maps to directory","errorType":"validation","errorClass":"fs.PathError","httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/fsys/fsys.go","lineNumber":660,"sourceCode":"\tinfo := stat(path)\n\tif info.deleted {\n\t\treturn nil, &fs.PathError{Op: op, Path: path, Err: fs.ErrNotExist}\n\t}\n\tif info.dir {\n\t\treturn fakeDir(filepath.Base(path)), nil\n\t}\n\tif info.replaced {\n\t\t// To keep the data model simple, if the overlay contains a symlink we\n\t\t// always stat through it (using Stat, not Lstat). That way we don't need to\n\t\t// worry about the interaction between Lstat and directories: if a symlink\n\t\t// in the overlay points to a directory, we reject it like an ordinary\n\t\t// directory.\n\t\tainfo, err := os.Stat(info.actual)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif ainfo.IsDir() {\n\t\t\treturn nil, &fs.PathError{Op: op, Path: path, Err: fmt.Errorf(\"overlay maps to directory\")}\n\t\t}\n\t\treturn fakeFile{name: filepath.Base(path), real: ainfo}, nil\n\t}\n\treturn osStat(path)\n}\n\n// fakeFile provides an fs.FileInfo implementation for an overlaid file,\n// so that the file has the name of the overlaid file, but takes all\n// other characteristics of the replacement file.\ntype fakeFile struct {\n\tname string\n\treal fs.FileInfo\n}\n\nfunc (f fakeFile) Name() string       { return f.name }\nfunc (f fakeFile) Size() int64        { return f.real.Size() }\nfunc (f fakeFile) Mode() fs.FileMode  { return f.real.Mode() }\nfunc (f fakeFile) ModTime() time.Time { return f.real.ModTime() }","sourceCodeStart":642,"sourceCodeEnd":678,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/fsys/fsys.go#L642-L678","documentation":"When stat'ing an overlaid path (one whose info.replaced is true), the target file on disk is found to be a directory. The overlay always stats through symlinks (using Stat, not Lstat), so if a symlink target resolves to a directory, it is treated the same as a direct directory mapping and rejected. This keeps the data model simple: overlay targets must be regular files.","triggerScenarios":"Calling fsys.Stat or fsys.Lstat on a path that has a replacement in the overlay, where the replacement target (info.actual) is a directory or a symlink resolving to a directory. The overlayStat function detects ainfo.IsDir()==true and returns this error.","commonSituations":"Overlay JSON points a file replacement at a directory path. A symlink target in the overlay was once a file but became a directory (e.g., after a git branch switch). Overlay generated from a different filesystem layout where the target structure changed.","solutions":["Look at the overlay entry for the path in the error message and verify its target is a regular file.","If the target is a symlink, check what it resolves to — it must not be a directory.","Replace the target path so it points to a specific regular file.","Remove the overlay entry entirely if the path should be a directory on disk."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Check overlay targets including symlink resolution for directory targets.\nfunc validateOverlayStatTargets(entries map[string]string) error {\n    for from, to := range entries {\n        if to == \"\" {\n            continue\n        }\n        info, err := os.Stat(to) // follows symlinks\n        if err != nil {\n            continue\n        }\n        if info.IsDir() {\n            return fmt.Errorf(\"overlay target %s resolves to directory %s\", from, to)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Stat (not Lstat) overlay targets to check they are not directories.","Verify symlinks in overlay targets do not resolve to directories.","Run a pre-build validation script on the overlay JSON."],"tags":["go","go-toolchain","overlay","fsys","symlinks","configuration"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}