gohugoio/hugo · error
npm pack: failed to open package file
Error message
npm pack: failed to open package file: %w
What it means
In npm.Pack (modules/npm/package_builder.go:168). While walking the _jsconfig virtual filesystem for module package files, for each collected entry it calls m.Open(); if the underlying file cannot be opened the error is wrapped. This operates on the Hugo virtual fs that merges all module mounts, so the failure is at the file-open layer.
Solutions
- Run 'hugo mod clean' then 'hugo mod tidy' to refresh the module cache.
- Check the mount source path in the offending module/theme actually exists and is readable.
- Remove or fix mounts that point at deleted package files.
Example fix
// before [[module.mounts]] source = "node_modules/pkg/package.json" target = "_jsconfig/package.json" // file missing on disk -> error // after: ensure the source exists, or drop the mount // (run `npm install` first, or remove the stale mount)
Defensive patterns
Strategy: validation
Validate before calling
// verify each mounted package file is openable before building
for _, m := range cfg.Module.Mounts {
if base := filepath.Base(m.Source); base == "package.json" || base == "package.hugo.json" {
full := filepath.Join(workDir, m.Source)
if f, err := os.Open(full); err != nil {
return fmt.Errorf("mount source %s not openable: %w", full, err)
} else { f.Close() }
}
} Prevention
- Keep module mounts pointing at real, readable files.
- Run 'hugo mod clean' / 'hugo mod tidy' when modules change.
- Avoid deleting files under a live 'hugo server'.
When it happens
Trigger: A module's mounted package.json/package.hugo.json entry exists in the virtual filesystem metadata but the backing file cannot be opened (permissions, broken symlink, race with file deletion, or a mount pointing to a removed path).
Common situations: A theme module mount referencing a package file that was deleted upstream; file permission issues in the module cache; symlinks in the module cache pointing nowhere; concurrent file changes during 'hugo server'.
Related errors
- abort: jekyll root contains neither posts nor drafts
- build filesystems
- could not determine content directory for
- create main fs
- already exists
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/e2921287b6b422ba.
Report an issue: GitHub.
Appendix: source
Thrown at modules/npm/package_builder.go:168
return nil
},
})
if err := w.Walk(); err != nil {
return err
}
// 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]View on GitHub (pinned to 52c9bd7908)