gohugoio/hugo · error

npm pack: could not locate existing workspaces array for…

Error message

npm pack: could not locate existing workspaces array for insertion

What it means

In ensureWorkspaceRef (modules/npm/package_builder.go:326). When workspaces is an array that does not already contain the workspace path, Hugo attempts a byte-level insertion by locating the ']' of the workspaces array in the raw file. If it cannot find the closing bracket reliably (malformed/reformatted layout), it gives up with this error rather than corrupting the file.

Solutions

  1. Reformat package.json with standard tooling (prettier / npm) so the workspaces array is conventionally formatted.
  2. Convert workspaces to the simpler array form and let Hugo rewrite it.
  3. Delete the workspaces key and let Hugo add a clean one.

Example fix

// before: oddly formatted workspaces array confusing the byte scan
"workspaces":[  "a","b" ]

// after: reformat
"workspaces": ["a", "b"]
Defensive patterns

Strategy: validation

Validate before calling

// reformat package.json so the workspaces array is conventionally laid out
data, _ := os.ReadFile("package.json")
var pkg map[string]any
if err := json.Unmarshal(data, &pkg); err != nil {
    return err
}
out, _ := json.MarshalIndent(pkg, "", "  ")
return os.WriteFile("package.json", append(out, '\n'), 0o666)

Prevention

When it happens

Trigger: package.json has a workspaces array but the raw bytes around it are shaped such that bytes.IndexByte for ']' after the workspaces key fails (e.g. the key appears but the array spans an unusual structure, or the file has non-standard formatting/escaping).

Common situations: Exotic JSON formatting tools; a workspaces key inside a string value that confuses byte scanning; manually mangled JSON that still parses but reorders braces; embedded quotes confusing the bracket scan.

Related errors


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

Appendix: source

Thrown at modules/npm/package_builder.go:326

					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]...)
					result = append(result, insertion...)
					result = append(result, data[pos:]...)
					return afero.WriteFile(fsys, packageJSONName, result, 0o666)
				}
			}
		}

		// We know a workspaces array exists but could not locate it reliably in the raw data.
		return fmt.Errorf("npm pack: could not locate existing workspaces array for insertion")
	}

	// No workspaces key — add before closing brace.
	lastBrace := bytes.LastIndexByte(data, '}')
	if lastBrace < 0 {
		return fmt.Errorf("npm pack: malformed package.json")
	}

	before := bytes.TrimRight(data[:lastBrace], " \t\n\r")
	needComma := len(before) > 0 && before[len(before)-1] != '{' && before[len(before)-1] != ','

	var insertion string
	if needComma {
		insertion = ",\n" + indent + `"workspaces": [` + "\n" + indent + indent + quoted + "\n" + indent + "]\n"
	} else {
		insertion = indent + `"workspaces": [` + "\n" + indent + indent + quoted + "\n" + indent + "]\n"
	}

View on GitHub (pinned to 52c9bd7908)