gohugoio/hugo · error
npm pack: unsupported workspaces type %T
Error message
npm pack: unsupported workspaces type %T
What it means
The `workspaces` field in the root package.json may be an array, an object with `packages`, or null/absent. Any other JSON type — a string, number, or boolean — is invalid per npm's schema, and Hugo rejects it with the concrete Go type (%T) rather than guessing an interpretation.
Source
Thrown at modules/npm/package_builder.go:299
// 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)
if err != nil {
return fmt.Errorf("npm pack: failed to marshal package.json with updated workspaces: %w", err)
}
updated = append(updated, '\n')
return afero.WriteFile(fsys, packageJSONName, updated, 0o666)
case nil:
// Treat explicit null as "no workspaces"; handled below as missing key.
default:
return fmt.Errorf("npm pack: unsupported workspaces type %T", v)
}
// Try adding to existing workspaces array when present.
if hasWS && wsVal != nil {
if wsIdx := bytes.Index(data, []byte(`"workspaces"`)); wsIdx >= 0 {
rest := data[wsIdx:]
if bracketOpen := bytes.IndexByte(rest, '['); bracketOpen >= 0 {
if bracketClose := bytes.IndexByte(rest[bracketOpen:], ']'); bracketClose >= 0 {
pos := wsIdx + bracketOpen + bracketClose
arrayContent := bytes.TrimSpace(data[wsIdx+bracketOpen+1 : pos])
var insertion string
if len(arrayContent) == 0 {
insertion = "\n" + indent + indent + quoted + "\n" + indent
} else {
insertion = ",\n" + indent + indent + quoted + "\n" + indent
}
result := make([]byte, 0, len(data)+len(insertion))
result = append(result, data[:pos]...)View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Wrap the value in an array: `"workspaces": ["packages/*"]`.
- If you intended the yarn object form, use `"workspaces": { "packages": ["packages/*"] }`.
- Validate against npm's package.json schema before re-running `hugo mod npm pack`.
Example fix
// before
{ "workspaces": "packages/*" }
// after
{ "workspaces": ["packages/*"] } Defensive patterns
Strategy: type-guard
Validate before calling
switch ws := pkg["workspaces"].(type) {
case []any, map[string]any, nil:
// supported
default:
return fmt.Errorf("workspaces must be an array or object, got %T", ws)
} Type guard
func isValidWorkspaces(v any) bool {
switch v.(type) {
case nil, []any, map[string]any:
return true
}
return false
} Prevention
- "workspaces" must be a JSON array of globs or an object with "packages" — never a string, number, or bool
- A common mistake is "workspaces": "packages/*" (bare string) — wrap it in an array
- Schema-validate package.json (e.g. against the npm package.json schema) in pre-commit
When it happens
Trigger: `hugo mod npm pack` reading a root package.json where `workspaces` is e.g. `"packages/*"` (a bare string), `true`, or a number — anything other than []any, map[string]any, or null.
Common situations: Writing `"workspaces": "packages/*"` instead of an array (a frequent hand-editing mistake); a templating/codegen step emitting the wrong type; copying a glob from docs without the surrounding brackets.
Related errors
- npm pack: unsupported workspaces object; missing "packages"
- 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/838649995811c264.json.
Report an issue: GitHub ↗.