golang/go · error · fs.PathError
deleted in overlay
Error message
deleted in overlay
What it means
The Go overlay filesystem (activated with the -overlay flag) allows certain files to be marked as deleted via a JSON configuration file. When Open() is called on such a path, the internal stat() function returns info.deleted=true and Open returns an fs.PathError with 'deleted in overlay'. This is the overlay mechanism's intentional way of representing files that should appear removed from the virtual source tree.
Solutions
- Inspect the overlay JSON file passed to -overlay for deleted entries matching the path
- Remove or correct the overlay configuration if the file should not be deleted
- Ensure the file exists on the real filesystem if the overlay deletion is stale
- Pass -overlay='' (empty) to disable the overlay entirely if it's not needed
- Regenerate the overlay configuration if it's produced by build tooling
Example fix
// before: overlay JSON marks file as deleted
// overlay.json:
// {"Replace": {}, "Delete": ["src/main.go"]}
// $ go build -overlay=overlay.json ./...
// # error: Open src/main.go: deleted in overlay
// after: remove the deletion entry or disable overlay
// overlay.json:
// {"Replace": {}, "Delete": []}
// $ go build -overlay=overlay.json ./...
// or simply:
// $ go build ./... Defensive patterns
Strategy: validation
Validate before calling
// Before building with an overlay, validate the overlay JSON for deleted paths.
import "encoding/json"
func validateOverlay(overlayPath string, requiredFiles []string) error {
data, err := os.ReadFile(overlayPath)
if err != nil {
return err
}
var overlay struct {
Replace map[string]string `json:"Replace"`
Delete []string `json:"Delete"`
}
if err := json.Unmarshal(data, &overlay); err != nil {
return err
}
deletedSet := make(map[string]bool)
for _, p := range overlay.Delete {
deletedSet[p] = true
}
for _, f := range requiredFiles {
if deletedSet[f] {
return fmt.Errorf("overlay deletes required file: %s", f)
}
}
return nil
} Type guard
// The error is returned as *fs.PathError with Op="Open".
import "io/fs"
func isOverlayDeleted(err error) bool {
var pathErr *fs.PathError
if errors.As(err, &pathErr) {
return pathErr.Op == "Open" && strings.Contains(pathErr.Err.Error(), "deleted in overlay")
}
return false
} Try / catch
// file, err := fsys.Open(path)
// if err != nil {
// if isOverlayDeleted(err) {
// // The file is intentionally deleted in the overlay.
// // Handle the absence or adjust the overlay config.
// return nil, fmt.Errorf("required file %s is deleted in overlay", path)
// }
// return nil, err
// } Prevention
- Review the overlay JSON file before builds to ensure no required files are accidentally deleted
- Regenerate overlay configs from source when project structure changes
- Use version control for overlay configs to track changes
- Pass -overlay='' when no overlay is needed to avoid stale configs
- Document which files are intentionally deleted in overlays and why
When it happens
Trigger: OverlayFS.Open(name) calls stat(name) which checks the overlay JSON configuration. The path is listed in the overlay's Replace or Delete map as deleted, so info.deleted is true. Open returns a PathError wrapping this message.
Common situations: A -overlay JSON file explicitly marks the file as deleted for conditional builds; build tooling generates an overlay to remove files for specific build configurations; CI configuration uses overlays to simulate file removal; stale overlay config from a previous build that no longer applies.
Related errors
- cannot open directory in overlay
- case-insensitive file name collision
- duplicate paths and in overlay map
- failed to create cache directory
- file is empty
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/942b12eeecee0cdd.
Report an issue: GitHub.
Appendix: source
Thrown at src/cmd/go/internal/fsys/fsys.go:564
return "", false
}
// Open opens the named file in the virtual file system.
// It must be an ordinary file, not a directory.
func Open(name string) (*os.File, error) {
Trace("Open", name)
bad := func(msg string) (*os.File, error) {
return nil, &fs.PathError{
Op: "Open",
Path: name,
Err: errors.New(msg),
}
}
info := stat(name)
if info.deleted {
return bad("deleted in overlay")
}
if info.dir {
return bad("cannot open directory in overlay")
}
if info.replaced {
name = info.actual
}
return os.Open(name)
}
// ReadFile reads the named file from the virtual file system
// and returns the contents.
func ReadFile(name string) ([]byte, error) {
f, err := Open(name)
if err != nil {
return nil, err
}View on GitHub (pinned to b6b368adc5)