golang/go · error
empty string key in overlay map
Error message
empty string key in overlay map
What it means
Returned by fsys.initFromJSON when the overlay's 'replace' map contains an empty-string key. An empty source path is meaningless for path replacement and would match every file, so it is rejected outright during sorted iteration of the replace map.
Solutions
- Open the overlay JSON and remove or fill in the empty-string key under 'replace'.
- If a generator builds the overlay, ensure no empty source paths are emitted (filter `if from == "" continue`).
- Validate the overlay with a small script that rejects empty replace keys before invoking go.
Example fix
// before — overlay.json
{ "replace": { "": "fallback.go" } }
// after — populate or omit the key
{ "replace": { "main.go": "fallback.go" } } Defensive patterns
Strategy: validation
Validate before calling
for from := range ojs.Replace {
if from == "" {
return fmt.Errorf("overlay 'replace' contains an empty-string key")
}
} Prevention
- When generating overlays, filter out empty source paths.
- Lint the overlay JSON for empty keys before committing.
- Treat an empty source path as a generator bug, not user input.
When it happens
Trigger: An overlay JSON whose replace object includes "": "something" as one of its entries.
Common situations: Programmatic overlay generators that emit an empty entry when the source path was unset; templating bugs; copy-paste artifacts leaving an empty key.
Related errors
- duplicate paths and in overlay map
- parsing overlay JSON
- reading overlay
- can only be set using the OS environment
- cannot be modified
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/fb02f1461d5065df.
Report an issue: GitHub.
Appendix: source
Thrown at src/cmd/go/internal/fsys/fsys.go:371
Trace("ReadFile", OverlayFile)
b, err := os.ReadFile(OverlayFile)
if err != nil {
return fmt.Errorf("reading overlay: %v", err)
}
return initFromJSON(b)
}
func initFromJSON(js []byte) error {
var ojs overlayJSON
if err := json.Unmarshal(js, &ojs); err != nil {
return fmt.Errorf("parsing overlay JSON: %v", err)
}
seen := make(map[string]string)
var list []replace
for _, from := range slices.Sorted(maps.Keys(ojs.Replace)) {
if from == "" {
return fmt.Errorf("empty string key in overlay map")
}
afrom := abs(from)
if old, ok := seen[afrom]; ok {
return fmt.Errorf("duplicate paths %s and %s in overlay map", old, from)
}
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:] {View on GitHub (pinned to b6b368adc5)