{"record":{"id":"6e38e67724e65e14","repo":"golang/go","slug":"cannot-embed-s-s-in-non-directory-s","errorCode":null,"errorMessage":"cannot embed %s %s: in non-directory %s","messagePattern":"cannot embed (.+?) (.+?): in non-directory (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/load/pkg.go","lineNumber":2211,"sourceCode":"\n\t\t\twhat := \"file\"\n\t\t\tinfo, err := fsys.Lstat(file)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, nil, err\n\t\t\t}\n\t\t\tif info.IsDir() {\n\t\t\t\twhat = \"directory\"\n\t\t\t}\n\n\t\t\t// Check that directories along path do not begin a new module\n\t\t\t// (do not contain a go.mod).\n\t\t\tfor dir := file; len(dir) > len(pkgdir)+1 && !dirOK[dir]; dir = filepath.Dir(dir) {\n\t\t\t\tif _, err := fsys.Stat(filepath.Join(dir, \"go.mod\")); err == nil {\n\t\t\t\t\treturn nil, nil, fmt.Errorf(\"cannot embed %s %s: in different module\", what, rel)\n\t\t\t\t}\n\t\t\t\tif dir != file {\n\t\t\t\t\tif info, err := fsys.Lstat(dir); err == nil && !info.IsDir() {\n\t\t\t\t\t\treturn nil, nil, fmt.Errorf(\"cannot embed %s %s: in non-directory %s\", what, rel, dir[len(pkgdir)+1:])\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdirOK[dir] = true\n\t\t\t\tif elem := filepath.Base(dir); isBadEmbedName(elem) {\n\t\t\t\t\tif dir == file {\n\t\t\t\t\t\treturn nil, nil, fmt.Errorf(\"cannot embed %s %s: invalid name %s\", what, rel, elem)\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn nil, nil, fmt.Errorf(\"cannot embed %s %s: in invalid directory %s\", what, rel, elem)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tswitch {\n\t\t\tdefault:\n\t\t\t\treturn nil, nil, fmt.Errorf(\"cannot embed irregular file %s\", rel)\n\n\t\t\tcase info.Mode().IsRegular():\n\t\t\t\tif have[rel] != pid {","sourceCodeStart":2193,"sourceCodeEnd":2229,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/load/pkg.go#L2193-L2229","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before: pkg/data is a file, //go:embed data/*\n// after: rename the file to data.txt and use\n//go:embed data_dir/*","handlingStrategy":"validation","validationCode":"// Confirm every intermediate path component of an embed target is a directory.\npackage embedcheck\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\nfunc AllAncestorsAreDirs(pkgDir, rel string) error {\n\tparts := strings.Split(filepath.ToSlash(rel), \"/\")\n\tcur := pkgDir\n\tfor i := 0; i < len(parts)-1; i++ {\n\t\tcur = filepath.Join(cur, parts[i])\n\t\tinfo, err := os.Lstat(cur)\n\t\tif err == nil && !info.IsDir() {\n\t\t\treturn errors.New(\"path component \" + cur + \" is not a directory\")\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["embed","filesystem","go-embed"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}