gohugoio/hugo · error

npm pack: unsupported workspaces type %T

Error message

npm pack: unsupported workspaces type %T

What it means

In ensureWorkspaceRef (modules/npm/package_builder.go:299). The workspaces field is type-switched; array ([]any), object (map[string]any) and nil are handled. Any other concrete type (e.g. a string or number) hits the default branch and returns 'unsupported workspaces type %T', printing the Go type.

Solutions

  1. Change workspaces to an array: "workspaces": ["apps/*"].
  2. Or use the object form: "workspaces": { "packages": ["apps/*"] }.
  3. Validate package.json shape against the npm spec.

Example fix

// before
"workspaces": "apps/*"

// after
"workspaces": ["apps/*"]
Defensive patterns

Strategy: type-guard

Validate before calling

var pkg map[string]any
_ = json.Unmarshal(data, &pkg)
switch pkg["workspaces"].(type) {
case []any, map[string]any, nil:
    // ok
default:
    return fmt.Errorf("workspaces must be array or object, got %T", pkg["workspaces"])
}

Type guard

func isSupportedWorkspaces(v any) bool {
    switch v.(type) {
    case []any, map[string]any, nil:
        return true
    }
    return false
}

Prevention

When it happens

Trigger: package.json has "workspaces": "apps/*" (a string) or "workspaces": 3 (a number). npm expects workspaces to be an array or an object with packages, so a scalar value is rejected.

Common situations: Typing workspaces as a single glob string instead of a one-element array; a config generator emitting the wrong shape; confusion with tools that accept string shortcuts.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/838649995811c264. Report an issue: GitHub.

Appendix: 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 52c9bd7908)