apache/answer · error
failed to create directory %s: %w
Error message
failed to create directory %s: %w
What it means
Inside copyDirEntries' fs.WalkDir callback, for every directory entry the destination directory is created with os.MkdirAll(dstPath, os.ModePerm). This error wraps a failed MkdirAll for the destination path — the target directory could not be created (or an intermediate parent exists as a file). It is the first failure point of any directory copy done by the build (UI files, plugins, vendor moves).
Source
Thrown at internal/cli/build.go:530
if ignoreThisDir(path) {
return nil
}
// Convert the path to use forward slashes, important because we use embedded FS which always uses forward slashes
path = filepath.ToSlash(path)
// Construct the absolute path for the source file/directory
srcPath := filepath.Join(sourceDir, path)
srcPath = filepath.ToSlash(srcPath)
// Construct the absolute path for the destination file/directory
dstPath := filepath.Join(targetDir, path)
if d.IsDir() {
// Create the directory in the destination
err := os.MkdirAll(dstPath, os.ModePerm)
if err != nil {
return fmt.Errorf("failed to create directory %s: %w", dstPath, err)
}
} else {
// Open the source file
srcFile, err := sourceFs.Open(srcPath)
if err != nil {
return fmt.Errorf("failed to open source file %s: %w", srcPath, err)
}
defer srcFile.Close()
// Create the destination file
dstFile, err := os.Create(dstPath)
if err != nil {
return fmt.Errorf("failed to create destination file %s: %w", dstPath, err)
}
defer dstFile.Close()
// Copy the file contents
_, err = io.Copy(dstFile, srcFile)View on GitHub (pinned to 3b9f137061)
Solutions
- Look at the wrapped %w cause and the %s path: if a file exists where a directory is needed, delete that stale file and re-run.
- Ensure the build user has write permission on the target parent directory (`chmod u+w` / run as the directory owner).
- Free disk space or raise the quota on the volume holding the build tmp dir.
- Clear the whole tmp build directory and rebuild from scratch to eliminate leftovers from prior failed runs.
Example fix
// caller-side prevention: start from a clean target os.RemoveAll(targetDir) os.MkdirAll(targetDir, os.ModePerm) err := copyDirEntries(os.DirFS(src), ".", targetDir, "node_modules")
Defensive patterns
Strategy: try-catch
Validate before calling
if fi, err := os.Lstat(targetDir); err == nil && !fi.IsDir() {
return fmt.Errorf("%s exists and is not a directory; remove it", targetDir)
}
parent := filepath.Dir(targetDir)
probe := filepath.Join(parent, ".mkdir-probe")
if err := os.WriteFile(probe, nil, 0o600); err != nil {
return fmt.Errorf("cannot write to %s: %w", parent, err)
}
os.Remove(probe) Type guard
func canMkdir(target string) bool {
// true if target is absent (creatable) or already a directory
fi, err := os.Lstat(target)
if err != nil { return errors.Is(err, os.ErrNotExist) }
return fi.IsDir()
} Try / catch
var perr *fs.PathError
err := copyDirEntries(sourceFs, sourceDir, targetDir, "node_modules")
if errors.As(err, &perr) && errors.Is(perr.Err, syscall.ENOTDIR) {
os.RemoveAll(perr.Path) // stale file where a dir is needed
err = copyDirEntries(sourceFs, sourceDir, targetDir, "node_modules")
}
if err != nil {
log.Printf("mkdir/copy failed: %v — check permissions and disk space on %s", err, targetDir)
}
return err Prevention
- Start every build from a clean tmp/target directory so no file sits where a directory must be created.
- Run builds as a user with write access to the destination volume; avoid read-only container layers.
- Monitor disk space and inode usage before long builds.
- Keep source paths short enough to stay under filesystem path/NAME_MAX limits.
- Fix the copyDirEntries wrapper to include the wrapped path in the message for faster diagnosis.
When it happens
Trigger: os.MkdirAll(dstPath, os.ModePerm) fails during a WalkDir over the source FS: destination parent path exists as a regular file, EACCES/EACCES-like permission denial on the target volume, ENOSPC or filesystem errors, or an overly long path.
Common situations: Previous build left a file where this build expects to create a directory (classic ENOTDIR); running the build in a read-only container layer or as a non-privileged user; tmp dir on a full/quota-limited disk; copying a dir tree whose deep paths exceed the filesystem's NAME_MAX/path limits.
Related errors
- failed to read plugins dir: %w
- failed to create destination file %s: %w
- failed to copy ui files: %w
- failed to open source file %s: %w
- create directory fail %s
AI-assisted analysis of apache/answer@3b9f137061 (2026-09-05).
Data as JSON: /api/errors/4c83eda56d45fd99.
Report an issue: GitHub.