golang/go · error
errors parsing go.work: %w
Error message
errors parsing go.work: %w
What it means
go.work bytes were read but modfile.ParseWork rejected them (syntax/grammar error). The parser error is wrapped with %w under 'errors parsing go.work:'. This is distinct from read failures (1067) and from semantic validation failures (1065, 1066).
Source
Thrown at src/cmd/go/internal/modload/init.go:844
if err := CheckGodebug("godebug", g.Key, g.Value); err != nil {
return nil, nil, fmt.Errorf("error loading go.work:\n%s:%d: %w", base.ShortPath(path), g.Syntax.Start.Line, err)
}
}
return wf, modRoots, nil
}
// ReadWorkFile reads and parses the go.work file at the given path.
func ReadWorkFile(path string) (*modfile.WorkFile, error) {
path = base.ShortPath(path) // use short path in any errors
workData, err := fsys.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("reading go.work: %w", err)
}
f, err := modfile.ParseWork(path, workData, nil)
if err != nil {
return nil, fmt.Errorf("errors parsing go.work:\n%w", err)
}
if f.Go != nil && gover.Compare(f.Go.Version, gover.Local()) > 0 && cfg.CmdName != "work edit" {
base.Fatal(&gover.TooNewError{What: base.ShortPath(path), GoVersion: f.Go.Version})
}
return f, nil
}
// WriteWorkFile cleans and writes out the go.work file to the given path.
func WriteWorkFile(path string, wf *modfile.WorkFile) error {
wf.SortBlocks()
wf.Cleanup()
out := modfile.Format(wf.Syntax)
return os.WriteFile(path, out, 0o666)
}
// UpdateWorkGoVersion updates the go line in wf to be at least goVers,
// reporting whether it changed the file.View on GitHub (pinned to b6b368adc5)
Solutions
- Open go.work and fix the syntax at the parser-reported line/column.
- Remove git merge conflict markers (<<<<<<< ======= >>>>>>>) if present.
- Regenerate with 'go work init ./m1 ./m2 ...' (or 'go work edit') to get a syntactically valid file, then re-apply customizations.
- Validate by running 'gofmt -e go.work' or re-running the failing command to see the precise parse location.
Example fix
// before (go.work)
use (
./svc-a
./svc-b
// missing closing paren
// errors parsing go.work: 4:1: expected ')'
// after
use (
./svc-a
./svc-b
) Defensive patterns
Strategy: validation
Validate before calling
// Parse go.work early to catch syntax errors with location.
data, err := os.ReadFile("go.work")
if err != nil && !os.IsNotExist(err) { return err }
if err == nil {
if _, perr := modfile.ParseWork("go.work", data, nil); perr != nil {
return fmt.Errorf("go.work parse error: %w", perr)
}
} Try / catch
out, err := exec.Command("go", "build", "./...").CombinedOutput()
if err != nil && bytes.Contains(out, []byte("errors parsing go.work")) {
// regenerate from known module list rather than guessing the fix
return fmt.Errorf("go.work malformed; recreate with 'go work init ...': %s", out)
}
return err Prevention
- Edit go.work only via 'go work edit' to keep syntax valid.
- Resolve git merge conflicts in go.work before building.
- Lint go.work with gofmt -e in pre-commit.
- Avoid smart-quotes / tabs introduced by editors.
When it happens
Trigger: go.work contains malformed syntax: unbalanced parens in a 'use ( ... )' block, stray tokens, bad directive verb, missing value, unterminated string. modfile.ParseWork returns a non-nil error and ReadWorkFile wraps it.
Common situations: Hand-edited go.work with a typo; merge conflict markers left in the file; a tool that writes partial go.work; copy-paste from docs that introduced smart quotes.
Related errors
- invalid time from git log: %q
- invalid module path %q
- error loading go.work: %s:%d: path %s appears multiple times
- error loading go.work: %s:%d: %w
- reading go.work: %w
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/4fecdb72bd264dec.
Report an issue: GitHub.