gohugoio/hugo · error

npm pack: failed to build

Error message

npm pack: failed to build: %w

What it means

In npm.Pack (modules/npm/package_builder.go:175). After processing all collected package entries via b.Add, if the builder accumulated any error in b.err it is wrapped as 'failed to build'. This is the aggregate/catch-all for a parse failure that occurred while adding a module's package file during the walk phase.

Solutions

  1. Inspect the module package files (the walk covers _jsconfig mounts of package.json/package.hugo.json) and validate each as JSON.
  2. Run 'hugo mod clean' and 'hugo mod tidy' to refresh modules.
  3. Temporarily set the offending module's usePackageJSON to 'never' to skip it.

Example fix

// before: a theme module ships
{ "name": "theme", "dependencies": { "x": } }
// -> 'npm pack: failed to build: invalid character '}' ...'

// after: fix the theme's package.json (or upgrade the theme)
{ "name": "theme", "dependencies": { "x": "^1.0" } }
Defensive patterns

Strategy: validation

Validate before calling

// validate every module's package.json/package.hugo.json as JSON
for _, m := range modules {
    for _, name := range []string{"package.json", "package.hugo.json"} {
        p := filepath.Join(m.Dir(), name)
        if data, err := os.ReadFile(p); err == nil {
            var v any
            if err := json.Unmarshal(data, &v); err != nil {
                return fmt.Errorf("%s: %w", p, err)
            }
        }
    }
}

Prevention

When it happens

Trigger: Any module package file (package.json or package.hugo.json mounted under _jsconfig) fails json.Unmarshal inside b.Add -> b.unmarshal, and the error surfaces here rather than at a specific earlier check.

Common situations: A theme/module ships a malformed package.json that passes the existence checks but fails JSON parsing; a stale module cache with a half-written package.json; a module whose package.hugo.json was hand-edited incorrectly.

Related errors


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

Appendix: source

Thrown at modules/npm/package_builder.go:175

	// Process collected entries: for each module, prefer package.hugo.json
	// over package.json at the root level. Workspace package.json files are always processed.
	for _, e := range entries {
		m := e.info.Meta()
		// Skip root-level package.json if this module has package.hugo.json.
		if !e.isHugoJSON && e.isRootLevel && modulesWithHugoJSON[m.ModulePath()] {
			continue
		}

		f, err := m.Open()
		if err != nil {
			return fmt.Errorf("npm pack: failed to open package file: %w", err)
		}
		b.Add(m.ModulePath(), f)
		f.Close()
	}

	if b.Err() != nil {
		return fmt.Errorf("npm pack: failed to build: %w", b.Err())
	}

	// 4. Build the autogenerated workspace package.json.
	// Exclude deps already defined by the project itself — they don't
	// need to be duplicated in the workspace and it simplifies maintenance.
	moduleDeps := make(map[string]any)
	moduleDepsComments := make(map[string]any)
	for k, v := range b.dependencies {
		if b.dependenciesComments[k] != "project" {
			moduleDeps[k] = v
			moduleDepsComments[k] = b.dependenciesComments[k]
		}
	}
	moduleDevDeps := make(map[string]any)
	moduleDevDepsComments := make(map[string]any)
	for k, v := range b.devDependencies {
		if b.devDependenciesComments[k] != "project" {
			moduleDevDeps[k] = v

View on GitHub (pinned to 52c9bd7908)