gohugoio/hugo · error

module %q not found in %q; either add it as a Hugo Module or

Error message

module %q not found in %q; either add it as a Hugo Module or store it in %q.

What it means

The primary 'module/theme not found' error. After all resolution paths fail (not a Go module, not downloadable, not in gomods), Hugo falls back to themesDir; if that directory does not exist, wrapModuleNotFound produces this user-facing message naming the module path, the looked-up themesDir path, and the themesDir location to store it. It tells the user the two valid ways to provide a module.

Source

Thrown at modules/collect.go:323

					mod = c.gomods.GetByPath(modulePath)
					if mod != nil {
						moduleDir = mod.Dir
					}
				}
			}

			// Fall back to project/themes/<mymodule>
			if moduleDir == "" {
				var err error
				moduleDir, err = c.createThemeDirname(modulePath, owner.projectMod || moduleImport.pathProjectReplaced)
				if err != nil {
					c.err = err
					return nil, nil
				}
				if found, _ := afero.Exists(c.fs, moduleDir); !found {
					//lint:ignore ST1005 end user message.
					c.err = c.wrapModuleNotFound(fmt.Errorf(`module %q not found in %q; either add it as a Hugo Module or store it in %q.`, modulePath, moduleDir, c.ccfg.ThemesDir))
					return nil, nil
				}
			}
		}
	}

	if found, _ := afero.Exists(c.fs, moduleDir); !found {
		c.err = c.wrapModuleNotFound(fmt.Errorf("%q not found", moduleDir))
		return nil, nil
	}

	if !strings.HasSuffix(moduleDir, fileSeparator) {
		moduleDir += fileSeparator
	}

	ma := &moduleAdapter{
		dir:          moduleDir,
		vendor:       vendored,

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Clone/install the theme into the themesDir shown in the error: `git clone <url> themes/mytheme`.
  2. Fix the import path spelling to match the installed folder or the Go module path exactly.
  3. If themesDir is overridden in config, place the theme under that configured directory.
  4. For a Go-module theme, ensure Hugo Modules are enabled (`hugo mod get github.com/x/y`) and go is installed.

Example fix

// before (hugo.toml)
[[module.imports]]
path = "my-them"  // typo
// after
[[module.imports]]
path = "my-theme"
// and ensure themes/my-theme exists:
git clone https://github.com/me/my-theme themes/my-theme
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check: theme folder or Go module must exist before build
import "os"

func ensureThemePresent(themesDir, importPath string) error {
  candidate := filepath.Join(themesDir, importPath)
  if _, err := os.Stat(candidate); err == nil { return nil }
  // not local -> must be a fetchable Go module
  return fmt.Errorf("%s missing under %s and not a Go module", importPath, themesDir)
}

Type guard

null

Try / catch

// On ErrorContains 'not found in', prompt the user to clone the theme or run `hugo mod get`.

Prevention

When it happens

Trigger: A `[[module.imports]] path = "mytheme"` where mytheme is neither a resolvable Go module path nor a directory under the configured themesDir (themes/mytheme). Also when module support is disabled (no go.mod/Hugo Modules) and the theme was never placed in themes/.

Common situations: Typo'd theme name, theme cloned into the wrong folder, themesDir overridden in config so themes live elsewhere than expected, missing `git clone` of the theme, or running on a fresh checkout without `--recurse-submodules` / `hugo mod get`.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/daddbded0ba789ae. Report an issue: GitHub.