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
- Inspect the module package files (the walk covers _jsconfig mounts of package.json/package.hugo.json) and validate each as JSON.
- Run 'hugo mod clean' and 'hugo mod tidy' to refresh modules.
- 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
- Validate module package files after 'hugo mod tidy'.
- Set usePackageJSON='never' on modules you don't want merged.
- Report broken package files to the module/theme author.
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
- npm pack: failed to marshal package.json with updated…
- npm pack: failed to parse package.json
- npm pack: failed to parse
- npm pack: malformed package.json
- npm pack: could not locate existing workspaces array for…
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] = vView on GitHub (pinned to 52c9bd7908)