gohugoio/hugo · error
failed to copy module file to vendor
Error message
failed to copy module file to vendor: %w
What it means
Returned by Client.Vendor when hugio.CopyFile fails copying a single-file mount's source to the vendor target (after the target dir was successfully created). Wrapped with %w. Indicates the source file became inaccessible between Stat and CopyFile, or the target write was rejected.
Solutions
- Inspect the wrapped error to distinguish read failure (source) from write failure (target).
- Re-run `hugo mod vendor` after stopping concurrent module downloads.
- Fix source read permissions or the target write permissions.
- Clear the module cache and re-download: `hugo mod clean` then vendor again.
Example fix
# before: cache file unreadable hugo mod vendor # CopyFile fails # after hugo mod clean hugo mod vendor
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify read access on source files and write access on target.
func copyable(fs afero.Fs, src, dst string) error {
f, err := fs.Open(src)
if err != nil {
return err
}
f.Close()
return fs.MkdirAll(filepath.Dir(dst), 0o755)
} Try / catch
if err := client.Vendor(); err != nil {
if strings.Contains(err.Error(), "failed to copy module file to vendor") {
// re-download module and retry; race or transient read failure
}
} Prevention
- Do not run `go mod download` concurrently with `hugo mod vendor`.
- Keep module cache readable; run `hugo mod clean` if files look corrupted.
When it happens
Trigger: Running `hugo mod vendor` for a file-type mount where CopyFile returns an error: source removed/unreadable mid-copy, target path not writable, or afero write rejection. The earlier Stat (452 path) succeeded, so this is a transient or write-side failure.
Common situations: Concurrent process modifying the module cache (e.g. `go mod download` racing with vendor); a file with no read permission even though the dir Stat passed; target disk full; antivirus/SELinux blocking the write.
Related errors
- failed to copy config dir to vendor dir
- failed to copy module to vendor dir
- failed to copy resources to vendor dir
- failed to make target dir
- failed to copy to
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/d4c2dc95e1b61057.
Report an issue: GitHub.
Appendix: source
Thrown at modules/client.go:256
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.
configDir := filepath.Join(dir, "config")
_, err = c.fs.Stat(configDir)
if err == nil {
if err := hugio.CopyDir(c.fs, configDir, filepath.Join(vendorDir, t.PathVersionQuery(true), "config"), nil); err != nil {View on GitHub (pinned to 52c9bd7908)