gohugoio/hugo · error
failed to make target dir
Error message
failed to make target dir: %w
What it means
Returned by Client.Vendor when c.fs.MkdirAll(targetDir, 0o755) fails for a file-type mount, before copying the file itself. targetDir is the parent of the vendored file path. Wrapped with %w. The file mount path is filepath.Join(vendorDir, pathVersion, mount.Source).
Solutions
- Read the wrapped error for the OS cause (permission, read-only, invalid name).
- Ensure the project working dir is writable: `chmod -R u+w .` or remove a stale _vendor dir.
- Delete _vendor and re-run `hugo mod vendor` to get a clean target tree.
- Avoid mount.Source paths that collide with file/directory names already vendored.
Example fix
# before: stale _vendor from a failed run blocks mkdir rm -rf _vendor hugo mod vendor # still fails due to perms # after chmod -R u+w . && rm -rf _vendor hugo mod vendor
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the _vendor tree is clean/writable before vendoring.
func prepareVendorDir(fs afero.Fs, dir string) error {
if err := fs.RemoveAll(dir); err != nil {
return err
}
return fs.MkdirAll(dir, 0o755)
} Try / catch
if err := client.Vendor(); err != nil {
if strings.Contains(err.Error(), "failed to make target dir") {
// remove stale _vendor, fix permissions, retry
}
} Prevention
- Delete _vendor before re-vendoring to avoid stale file/dir conflicts.
- Confirm the working directory is writable.
- Avoid Windows-reserved names in mount.Source paths.
When it happens
Trigger: Running `hugo mod vendor` where a mount source is a single file whose target parent directory cannot be created: permission denied, read-only filesystem, invalid path characters, or a path collision with an existing file.
Common situations: Working directory or _vendor is read-only; a previous failed vendor left a file where a directory is now expected; OS path restrictions (Windows reserved names); running Hugo as a user lacking write access to the project.
Related errors
- failed to copy config dir to vendor dir
- failed to copy module file to vendor
- failed to copy module to vendor dir
- failed to copy resources to vendor dir
- failed to open dir
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/e39864ac83245b91.
Report an issue: GitHub.
Appendix: source
Thrown at modules/client.go:252
dir := t.Dir()
for _, mount := range t.Mounts() {
sourceFilename := filepath.Join(dir, mount.Source)
targetFilename := filepath.Join(vendorDir, t.PathVersionQuery(true), mount.Source)
fi, err := c.fs.Stat(sourceFilename)
if err != nil {
return fmt.Errorf("failed to vendor module: %w", err)
}
if fi.IsDir() {
if err := hugio.CopyDir(c.fs, sourceFilename, targetFilename, nil); err != nil {
return fmt.Errorf("failed to copy module to vendor dir: %w", err)
}
} else {
targetDir := filepath.Dir(targetFilename)
if err := c.fs.MkdirAll(targetDir, 0o755); err != nil {
return fmt.Errorf("failed to make target dir: %w", err)
}
if err := hugio.CopyFile(c.fs, sourceFilename, targetFilename); err != nil {
return fmt.Errorf("failed to copy module file to vendor: %w", err)
}
}
}
// Include the resource cache if present.
resourcesDir := filepath.Join(dir, files.FolderResources)
_, err := c.fs.Stat(resourcesDir)
if err == nil {
if err := hugio.CopyDir(c.fs, resourcesDir, filepath.Join(vendorDir, t.PathVersionQuery(true), files.FolderResources), nil); err != nil {
return fmt.Errorf("failed to copy resources to vendor dir: %w", err)
}
}
// Include the config directory if present.View on GitHub (pinned to 52c9bd7908)