golang/go · error
cannot embed %s %s: in non-directory %s
Error message
cannot embed %s %s: in non-directory %s
What it means
In the same ancestor walk (line 2210), for each non-leaf ancestor directory the loader Lstat's it; if it exists but is NOT a directory (a regular file or irregular file sitting where a path component is expected), embedding is impossible. The offending intermediate component is reported relative to pkgdir.
Source
Thrown at src/cmd/go/internal/load/pkg.go:2211
what := "file"
info, err := fsys.Lstat(file)
if err != nil {
return nil, nil, err
}
if info.IsDir() {
what = "directory"
}
// Check that directories along path do not begin a new module
// (do not contain a go.mod).
for dir := file; len(dir) > len(pkgdir)+1 && !dirOK[dir]; dir = filepath.Dir(dir) {
if _, err := fsys.Stat(filepath.Join(dir, "go.mod")); err == nil {
return nil, nil, fmt.Errorf("cannot embed %s %s: in different module", what, rel)
}
if dir != file {
if info, err := fsys.Lstat(dir); err == nil && !info.IsDir() {
return nil, nil, fmt.Errorf("cannot embed %s %s: in non-directory %s", what, rel, dir[len(pkgdir)+1:])
}
}
dirOK[dir] = true
if elem := filepath.Base(dir); isBadEmbedName(elem) {
if dir == file {
return nil, nil, fmt.Errorf("cannot embed %s %s: invalid name %s", what, rel, elem)
} else {
return nil, nil, fmt.Errorf("cannot embed %s %s: in invalid directory %s", what, rel, elem)
}
}
}
switch {
default:
return nil, nil, fmt.Errorf("cannot embed irregular file %s", rel)
case info.Mode().IsRegular():
if have[rel] != pid {View on GitHub (pinned to b6b368adc5)
Solutions
- Rename or remove the file that is occupying a path component that should be a directory.
- Correct the //go:embed pattern to point at the real directory.
- Ensure any intermediate symlinks resolve to directories (and remember go:embed forbids symlinked directories entirely).
Example fix
// before: pkg/data is a file, //go:embed data/* // after: rename the file to data.txt and use //go:embed data_dir/*
Defensive patterns
Strategy: validation
Validate before calling
// Confirm every intermediate path component of an embed target is a directory.
package embedcheck
import (
"errors"
"os"
"path/filepath"
"strings"
)
func AllAncestorsAreDirs(pkgDir, rel string) error {
parts := strings.Split(filepath.ToSlash(rel), "/")
cur := pkgDir
for i := 0; i < len(parts)-1; i++ {
cur = filepath.Join(cur, parts[i])
info, err := os.Lstat(cur)
if err == nil && !info.IsDir() {
return errors.New("path component " + cur + " is not a directory")
}
}
return nil
} Prevention
- Do not let a regular file share a name with a directory the embed pattern expects.
- Avoid symlinks in embedded trees; go:embed forbids symlinked directories anyway.
When it happens
Trigger: An embed glob like `data/*.txt` matches `data/x` where `data` is actually a file, not a directory; or a glob like `a/b/c` where `a/b` is a file. The glob matched because fsys.Glob is permissive but the path is structurally invalid for embedding.
Common situations: A leftover file with the same name as an expected directory; a symlink chain where an intermediate node is a file; case-sensitivity mismatches between a case-insensitive dev box and Linux CI producing phantom matches.
Related errors
- cannot embed %s %s: invalid name %s
- cannot embed %s %s: in invalid directory %s
- cannot embed irregular file %s
- cannot embed file %s: invalid name %s
- cannot embed directory %s: contains no embeddable files
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/6e38e67724e65e14.
Report an issue: GitHub.