gohugoio/hugo · error

npm pack: could not locate existing workspaces array for ins

Error message

npm pack: could not locate existing workspaces array for insertion

What it means

To preserve the user's package.json formatting, Hugo inserts its workspace path into the existing `workspaces` array by raw byte manipulation: it searches for the literal `"workspaces"` key and the following `[`/`]` brackets. If the parsed JSON says a workspaces array exists but that byte-level scan can't find it, Hugo aborts rather than risk corrupting the file.

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 8a468df065)

Solutions

  1. Reformat package.json conventionally (e.g. `npx prettier --write package.json` or `jq . package.json > tmp && mv tmp package.json`) and re-run.
  2. Manually add the Hugo workspace path (`_hugo_packages` autogen folder shown in the generated config) to the `workspaces` array yourself; Hugo then detects it as already present.
  3. Rename or restructure any other `"workspaces"` string literals that appear before the real key.
Defensive patterns

Strategy: validation

Validate before calling

// the builder inserts entries into an existing workspaces array textually;
// verify the array literal is present and well-formed
if bytes.Contains(data, []byte("\"workspaces\"")) && !regexp.MustCompile(`"workspaces"\s*:\s*(\[|\{)`).Match(data) {
    return errors.New("workspaces key present but not followed by an array/object literal")
}

Prevention

When it happens

Trigger: `hugo mod npm pack` with a package.json that json-parses to an array-form `workspaces`, but where the byte scan fails — e.g. unusual escaping of the key, the first `"workspaces"` occurrence in the raw bytes being a different string (a dependency name or nested value appearing before the real key with no `[` after it in an expected position).

Common situations: Exotic formatting or minified package.json where another `"workspaces"` string literal precedes the actual key; files with unusual whitespace/encoding that defeat the heuristic scan.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/0a2af35ec0405acc.json. Report an issue: GitHub ↗.