gohugoio/hugo · error
npm pack: unsupported workspaces object; missing "packages"
Error message
npm pack: unsupported workspaces object; missing "packages" field
What it means
When ensuring the root package.json references Hugo's autogenerated workspace, Hugo supports `workspaces` either as an array or as the yarn-classic object form `{ "packages": [...] }`. If `workspaces` is an object but has no `packages` key, Hugo cannot know where to insert its workspace path and refuses to guess, failing fast per its no-silent-fallback policy.
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 8a468df065)
Solutions
- Add a `packages` array to the workspaces object: `"workspaces": { "packages": [] }` — Hugo will then append its workspace path.
- Or simplify to the array form: `"workspaces": []`.
- Re-run `hugo mod npm pack` after the change.
Example fix
// before
{ "workspaces": { "nohoist": ["**/foo"] } }
// after
{ "workspaces": { "packages": [], "nohoist": ["**/foo"] } } Defensive patterns
Strategy: validation
Validate before calling
var pkg struct{ Workspaces any `json:"workspaces"` }
json.Unmarshal(data, &pkg)
if m, ok := pkg.Workspaces.(map[string]any); ok {
if _, ok := m["packages"]; !ok {
return errors.New("workspaces object must contain a \"packages\" array")
}
} Type guard
func hasPackagesField(ws any) bool {
m, ok := ws.(map[string]any)
if !ok { return false }
_, ok = m["packages"].([]any)
return ok
} Prevention
- Prefer the simple array form: "workspaces": ["pkg-a", "pkg-b"]
- If using the object form (yarn style), always include a "packages" array field
- Validate package.json workspaces shape in CI before running hugo mod npm pack
When it happens
Trigger: `hugo mod npm pack` on a project whose root package.json has `"workspaces": {}` or an object containing only yarn-specific fields like `nohoist` without `packages`.
Common situations: Yarn workspaces configs that use `nohoist` but omitted `packages`; hand-migrated monorepo configs; tooling that wrote an empty workspaces object placeholder.
Related errors
- npm pack: unsupported workspaces type %T
- npm pack: failed to parse package.json: %w
- npm pack: failed to build: %w
- npm pack: could not locate existing workspaces array for ins
- npm pack: malformed package.json
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/553658021d055bb6.json.
Report an issue: GitHub ↗.