gohugoio/hugo · error

failed to copy config dir to vendor dir: %w

Error message

failed to copy config dir to vendor dir: %w

What it means

In `hugo mod vendor` (modules/client.go:275), Hugo copies a module's `config` directory (config/_default, environment configs, module imports) into _vendor/<module>/config when present, because that configuration must travel with the vendored module. This error wraps a failure of that recursive copy.

Source

Thrown at modules/client.go:275

				}
			}
		}

		// 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 {
			if err := hugio.CopyFile(c.fs, configFile, filepath.Join(vendorDir, t.PathVersionQuery(true), filepath.Base(configFile))); err != nil {
				if !herrors.IsNotExist(err) {
					return err
				}
			}
		}
	}

	if modulesContent.Len() > 0 {

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Delete _vendor and re-run hugo mod vendor to clear partial state.
  2. Ensure read access to the module's config directory in the module cache and write access under the project.
  3. Check the wrapped error's path for the specific file; fix its permissions or the disk-space issue.
  4. If the cache seems corrupt, run go clean -modcache (or hugo mod clean) and re-download.
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the module's config dir before vendoring
cfgDir := filepath.Join(mod.Dir(), "config")
if fi, err := os.Stat(cfgDir); err == nil && !fi.IsDir() {
    return fmt.Errorf("module config path %q is not a directory", cfgDir)
}

Try / catch

if err := client.Vendor(); err != nil {
    if strings.Contains(err.Error(), "failed to copy config dir to vendor dir") {
        return fmt.Errorf("module's config/ dir could not be vendored — check permissions and symlinks: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: The module has a `config` directory (Stat succeeds) but hugio.CopyDir(c.fs, configDir, <vendorDir>/<module>/config, nil) fails — permission or I/O errors reading the module's config tree or writing under _vendor/.

Common situations: Modules using the config-directory layout (config/_default/hugo.toml) vendored from a cache with odd permissions; read-only project checkouts; leftovers from a previous partial vendor conflicting with the target path; disk full.

Related errors


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