gohugoio/hugo · error
npm pack: unsupported workspaces object; missing "packages"…
Error message
npm pack: unsupported workspaces object; missing "packages" field
What it means
In ensureWorkspaceRef (modules/npm/package_builder.go:272). When the root package.json uses the object form of 'workspaces' ("workspaces": { ... }), Hugo requires a "packages" field inside it (the npm/yarn convention). If the object lacks "packages", the structure is unsupported and the error is returned without a wrapped cause.
Solutions
- Restructure the workspaces field to the standard object form: "workspaces": { "packages": ["pkg-a", "pkg-b"] }.
- Or use the simpler array form: "workspaces": ["pkg-a", "pkg-b"], which Hugo also supports.
- Ensure no extraneous keys replaced 'packages'.
Example fix
// before
"workspaces": { "apps": ["apps/*"] }
// after
"workspaces": { "packages": ["apps/*"] }
// or simply
"workspaces": ["apps/*"] Defensive patterns
Strategy: type-guard
Validate before calling
// ensure workspaces object form has packages
data, _ := os.ReadFile("package.json")
var pkg map[string]any
_ = json.Unmarshal(data, &pkg)
if ws, ok := pkg["workspaces"].(map[string]any); ok {
if _, hasPkgs := ws["packages"]; !hasPkgs {
return errors.New(`workspaces object must contain "packages"`)
}
} Type guard
func isSupportedWorkspacesArrayForm(v any) bool {
switch v.(type) {
case []any, map[string]any, nil:
return true
}
return false
} Prevention
- Use the array workspaces form for simplicity.
- If using object form, always include packages.
- Validate package.json structure in CI.
When it happens
Trigger: package.json contains "workspaces": { "nope": [...] } or an object form of workspaces without a packages key. This can happen with exotic monorepo tooling or hand-edited configs.
Common situations: Switching a project to/from pnpm-style workspaces without the packages key; a tool that writes a workspaces object with a different key; manually restructuring workspaces.
Related errors
- npm pack: could not locate existing workspaces array for…
- npm pack: failed to marshal package.json with updated…
- npm pack: unsupported workspaces type %T
- npm pack: failed to build
- npm pack: failed to open package file
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/553658021d055bb6.
Report an issue: GitHub.
Appendix: source
Thrown at modules/npm/package_builder.go:272
quoted := fmt.Sprintf("%q", workspacePath)
wsVal, hasWS := pkg["workspaces"]
switch v := wsVal.(type) {
case []any:
// Array form: ["pkg-a", "pkg-b", ...]
if slices.Contains(toStringSlice(v), workspacePath) {
if runtime.GOOS == "windows" {
return afero.WriteFile(fsys, packageJSONName, data, 0o666)
}
return nil
}
// Fall through to byte-based insertion into the existing array below.
case map[string]any:
// Object form: { "workspaces": { "packages": [...] } }
packagesVal, ok := v["packages"]
if !ok {
return fmt.Errorf("npm pack: unsupported workspaces object; missing \"packages\" field")
}
packagesSlice := toStringSlice(packagesVal)
if slices.Contains(packagesSlice, workspacePath) {
if runtime.GOOS == "windows" {
return afero.WriteFile(fsys, packageJSONName, data, 0o666)
}
return nil
}
// Append the new workspace path to the packages slice.
newPkgs := make([]any, 0, len(packagesSlice)+1)
for _, s := range packagesSlice {
newPkgs = append(newPkgs, s)
}
newPkgs = append(newPkgs, workspacePath)
v["packages"] = newPkgs
updated, err := json.MarshalIndent(pkg, "", indent)View on GitHub (pinned to 52c9bd7908)