gohugoio/hugo · error

failed to copy resources to vendor dir: %w

Error message

failed to copy resources to vendor dir: %w

What it means

In `hugo mod vendor` (modules/client.go:266), Hugo also vendors a module's `resources` directory (the resource/asset cache, e.g. processed images) when it exists, so vendored builds don't need to re-generate those resources. This error wraps a failure of that recursive CopyDir into _vendor/<module>/resources.

Source

Thrown at modules/client.go:266

			} 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 {
				return fmt.Errorf("failed to copy config dir to vendor dir: %w", err)
			}
		}

		// Also include any theme.toml or config.* or hugo.* files in the root.
		configFiles, _ := afero.Glob(c.fs, filepath.Join(dir, "config.*"))
		configFiles2, _ := afero.Glob(c.fs, filepath.Join(dir, "hugo.*"))
		configFiles = append(configFiles, configFiles2...)
		configFiles = append(configFiles, filepath.Join(dir, "theme.toml"))
		for _, configFile := range configFiles {

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Check disk space — the resources cache is often the largest thing vendored.
  2. Fix permissions on the module's resources directory and on the project _vendor target, then retry.
  3. If the module's resource cache is corrupt or unneeded, remove it upstream (or in the module cache after go clean -modcache) and re-vendor; Hugo will regenerate resources at build time.
  4. Read the wrapped error for the specific failing file.
Defensive patterns

Strategy: try-catch

Validate before calling

// If the module has a resources cache dir, ensure it's intact
resourcesDir := filepath.Join(mod.Dir(), "resources")
if fi, err := os.Stat(resourcesDir); err == nil && !fi.IsDir() {
    return fmt.Errorf("module resources path %q is not a directory", resourcesDir)
}

Try / catch

if err := client.Vendor(); err != nil {
    if strings.Contains(err.Error(), "failed to copy resources to vendor dir") {
        // resources/ is a cache — clearing it in the module and re-vendoring is safe
        return fmt.Errorf("module resources dir could not be copied; clear and retry: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: The module directory contains a `resources` folder (Stat succeeds) but hugio.CopyDir to the vendor dir fails — unreadable cached resource files, write/permission errors under _vendor/, or disk exhaustion (resource caches can be large).

Common situations: Large image-processing caches filling the disk during vendoring; permission mismatches on resources generated by a different user/CI job; corrupted or partially written resource cache files.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/e48b29a964168abd.json. Report an issue: GitHub ↗.