wavetermdev/waveterm · error
gofmt not found at %s: %w
Error message
gofmt not found at %s: %w
What it means
ResolveGoFmtPath locates the gofmt binary next to the configured/discovered Go toolchain (settings.TsunamiGoPath, falling back to build.FindGoExecutable) and stats <goDir>/gofmt[.exe]. If os.Stat fails, the error is wrapped as 'gofmt not found at %s'. It means the Go installation directory does not contain a gofmt binary.
Source
Thrown at pkg/waveapputil/waveapputil.go:51
if goPath == "" {
var err error
goPath, err = build.FindGoExecutable()
if err != nil {
return "", err
}
}
goDir := filepath.Dir(goPath)
gofmtName := "gofmt"
if runtime.GOOS == "windows" {
gofmtName = "gofmt.exe"
}
gofmtPath := filepath.Join(goDir, gofmtName)
info, err := os.Stat(gofmtPath)
if err != nil {
return "", fmt.Errorf("gofmt not found at %s: %w", gofmtPath, err)
}
if info.IsDir() {
return "", fmt.Errorf("gofmt path is a directory: %s", gofmtPath)
}
if info.Mode()&0111 == 0 {
return "", fmt.Errorf("gofmt is not executable: %s", gofmtPath)
}
return gofmtPath, nil
}
func FormatGoCode(contents []byte) []byte {
gofmtPath, err := ResolveGoFmtPath()
if err != nil {
return contents
}View on GitHub (pinned to a4447c1563)
Solutions
- Check the resolved path in the error and install/move gofmt there (it ships with the Go toolchain)
- Fix the TsunamiGoPath setting to point to a real Go installation (directory containing go and gofmt)
- Run 'which go' / 'go env GOROOT' and verify gofmt exists at GOROOT/bin/gofmt
- Reinstall Go if the toolchain is incomplete
Example fix
// before // settings.TsunamiGoPath = "/opt/old-go/bin/go" (stale, gofmt missing) // after // settings.TsunamiGoPath = "/usr/local/go/bin/go" // ls /usr/local/go/bin -> go gofmt
Defensive patterns
Strategy: validation
Validate before calling
goPath := settings.TsunamiGoPath
if goPath == "" { goPath, _ = build.FindGoExecutable() }
gofmt := filepath.Join(filepath.Dir(goPath), gofmtName())
if _, err := os.Stat(gofmt); err != nil {
return fmt.Errorf("precheck: %w", err)
} Type guard
func gofmtAvailable() bool {
p, err := waveapputil.ResolveGoFmtPath()
return err == nil && p != ""
} Try / catch
// FormatGoCode silently falls back to unformatted content on error;
// call ResolveGoFmtPath directly to surface the problem:
if _, err := waveapputil.ResolveGoFmtPath(); err != nil {
log.Printf("gofmt unavailable, formatting disabled: %v", err)
} Prevention
- Keep TsunamiGoPath pointing at a complete Go installation
- After Go upgrades, verify GOROOT/bin still contains gofmt
- Never copy only the 'go' binary without its sibling tools
When it happens
Trigger: Calling FormatGoFile/FormatGoCode when gofmt is absent from the resolved Go bin directory: os.Stat returns ENOENT (file missing) or the path is otherwise unstattable (broken symlink, permission on parent dir).
Common situations: TsunamiGoPath setting points at a non-Go directory or a stale path after a Go upgrade/uninstall; only the go binary was copied without the rest of the toolchain; partial Go installation (gofmt removed by antivirus or cleanup tool); PATH finds 'go' but bin dir is incomplete.
Related errors
- failed to get app directory: %w
- failed to get builder executable path: %w
- build failed: %w
- build output not found: %w
- failed to read app manifest: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/a02574960e7de3aa.
Report an issue: GitHub.