golang/go · error
inconsistent files %s and %s in overlay map
Error message
inconsistent files %s and %s in overlay map
What it means
The Go overlay filesystem (enabled via -overlay flag pointing to a JSON file) maps virtual paths to real files. This error fires during overlay initialization when a path is mapped as a file (has a non-empty 'to' target) while simultaneously having a child path also mapped as a file, implying the parent is a directory. A single path cannot be both a file and a directory, so the overlay is rejected as internally inconsistent.
Source
Thrown at src/cmd/go/internal/fsys/fsys.go:395
seen[afrom] = from
list = append(list, replace{from: afrom, to: abs(ojs.Replace[from])})
}
slices.SortFunc(list, func(x, y replace) int { return cmp(x.from, y.from) })
for i, r := range list {
if r.to == "" { // deleted
continue
}
// have file for r.from; look for child file implying r.from is a directory
prefix := r.from + string(filepath.Separator)
for _, next := range list[i+1:] {
if !strings.HasPrefix(next.from, prefix) {
break
}
if next.to != "" {
// found child file
return fmt.Errorf("inconsistent files %s and %s in overlay map", r.from, next.from)
}
}
}
overlay = list
return nil
}
// IsDir returns true if path is a directory on disk or in the
// overlay.
func IsDir(path string) (bool, error) {
Trace("IsDir", path)
switch info := stat(path); {
case info.dir:
return true, nil
case info.deleted, info.replaced:
return false, nilView on GitHub (pinned to b6b368adc5)
Solutions
- Inspect the two paths named in the error — the parent is treated as both a file and a directory in the overlay JSON.
- If the parent should be a file, remove child entries that place files beneath it (e.g., delete the '/proj/foo.go/bar.go' entry).
- If the parent should be a directory, ensure the parent entry itself is not mapped to a file target — either remove it or mark it as deleted (empty 'to').
- Regenerate the overlay JSON from scratch, ensuring each replaced path is unambiguously a file or deleted.
Example fix
// before — overlay JSON is inconsistent
{
"Replace": {
"/proj/main.go": "/real/main.go",
"/proj/main.go/util.go": "/real/util.go"
}
}
// after — main.go is a file only
{
"Replace": {
"/proj/main.go": "/real/main.go"
}
} Defensive patterns
Strategy: validation
Validate before calling
// Validate overlay JSON for parent/child file conflicts before use.
func validateOverlay(entries map[string]string) error {
var paths []string
for from, to := range entries {
if to != "" {
paths = append(paths, from)
}
}
sort.Strings(paths)
for i, a := range paths {
prefix := a + string(filepath.Separator)
for _, b := range paths[i+1:] {
if !strings.HasPrefix(b, prefix) {
break
}
return fmt.Errorf("inconsistent overlay: %s is both file and parent of %s", a, b)
}
}
return nil
} Prevention
- Validate the overlay JSON structure before passing it to -overlay.
- Use a test harness that checks overlay consistency on load.
- Generate overlay maps programmatically rather than hand-editing.
When it happens
Trigger: Passing -overlay=overlay.json where the Replace map contains both '/proj/foo.go' -> '/real/foo.go' and '/proj/foo.go/bar.go' -> '/real/bar.go'. The first entry treats foo.go as a file; the second implies it is a directory containing bar.go. The sorted-path scan in initFromJSON detects this parent/child conflict.
Common situations: Hand-editing overlay JSON files for test harnesses or IDE integration. Automated overlay generators that don't validate parent/child relationships. Copying overlay entries between different directory layouts where a path changes from directory to file. Mistakenly replacing a path that should be a directory with a file mapping.
Related errors
- overlay maps child %s to directory
- overlay maps to directory
- total length of command line and environment variables excee
- deleted in overlay
- cannot open directory in overlay
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/28d5d8a824fe0f11.
Report an issue: GitHub.