gohugoio/hugo · error
invalid modules list
Error message
invalid modules list: %q
What it means
collectModulesTXT parses _vendor/modules.txt line by line; each line must have exactly two whitespace fields (module path and version). Any line with != 2 fields aborts vendor parsing with the offending filename. The file is normally generated by `go mod vendor`, so a malformed line implies manual edits or corruption.
Solutions
- Regenerate the vendor directory: `hugo mod vendor` (or `go mod vendor`) to produce a canonical modules.txt.
- If you must hand-edit, ensure every non-comment line is exactly `path version`.
- Inspect the file: `cat _vendor/modules.txt` and find the line with the wrong field count.
- Remove the stale _vendor dir entirely if vendoring is not intended (`rm -rf _vendor`).
Example fix
// before: a malformed line in _vendor/modules.txt # github.com/x/y v1.2.3 extra-note github.com/x/y v1.2.3 // after: regenerate rm -rf _vendor && hugo mod vendor
Defensive patterns
Strategy: validation
Validate before calling
// Lint a vendor/modules.txt before Hugo parses it
import ("bufio"; "os"; "strings")
func lintModulesTxt(path string) error {
f, err := os.Open(path)
if err != nil { return err }
defer f.Close()
s := bufio.NewScanner(f)
for s.Scan() {
line := strings.TrimSpace(strings.TrimPrefix(strings.TrimSpace(s.Text()), "# "))
if line == "" { continue }
if len(strings.Fields(line)) != 2 { return fmt.Errorf("bad line: %q", line) }
}
return s.Err()
} Type guard
null
Try / catch
// On 'invalid modules list:', regenerate vendor/ rather than patching by hand.
Prevention
- Generate _vendor only via `hugo mod vendor` / `go mod vendor`.
- Never hand-edit modules.txt; re-vendor after dep changes.
- In CI, fail if modules.txt differs from regenerated output.
When it happens
Trigger: A _vendor/modules.txt containing a comment line that wasn't stripped, a wrapped/truncated line, a hand-merged file with stray text, or a vendor dir produced by a tool that diverges from go's format.
Common situations: Manually editing modules.txt to add/remove a vendored dep, a bad merge conflict resolution leaving a 3-field or 1-field line, or a pre-Go-1.14 vendor format.
Related errors
- failed to apply mounts for project
- module not found in ; either add it as a Hugo Module or…
- : : mount source must be a local path for modules/themes
- cannot vendor module
- could not determine content directory for
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/33cfe671439302da.
Report an issue: GitHub.
Appendix: source
Thrown at modules/collect.go:625
return err
}
defer f.Close()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
// # github.com/alecthomas/chroma v0.6.3
line := scanner.Text()
line = strings.Trim(line, "# ")
line = strings.TrimSpace(line)
if line == "" {
continue
}
parts := strings.Fields(line)
if len(parts) != 2 {
return fmt.Errorf("invalid modules list: %q", filename)
}
path := parts[0]
shouldAdd := c.Client.moduleConfig.VendorClosest
if !shouldAdd {
if _, found := c.vendored[path]; !found {
shouldAdd = true
}
}
if shouldAdd {
c.vendored[path] = vendoredModule{
Owner: owner,
Dir: filepath.Join(vendorDir, path),
Version: parts[1],
}
}View on GitHub (pinned to 52c9bd7908)