wavetermdev/waveterm · error
gofmt is not executable: %s
Error message
gofmt is not executable: %s
What it means
After confirming the gofmt path exists and is a file, ResolveGoFmtPath checks the executable bit (info.Mode()&0111). If no execute permission is set, it returns 'gofmt is not executable: %s' rather than letting exec fail later. (On Windows this check is effectively always satisfied.)
Source
Thrown at pkg/waveapputil/waveapputil.go:59
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
}
cmd := exec.Command(gofmtPath)
cmd.Stdin = bytes.NewReader(contents)
formattedOutput, err := cmd.Output()
if err != nil {
return contents
}
View on GitHub (pinned to a4447c1563)
Solutions
- chmod +x <gofmt path> on the reported path
- Re-copy the binary preserving modes: 'install -m 755 src dst' or extract with a tool that preserves permissions
- Check the mount options (noexec) and remount with exec if applicable
- Verify with 'ls -l' that the owner has execute permission
Example fix
// before -rw-r--r-- gofmt // after # chmod +x /usr/local/go/bin/gofmt -rwxr-xr-x gofmt
Defensive patterns
Strategy: validation
Validate before calling
p, err := waveapputil.ResolveGoFmtPath()
if err != nil { return err }
if info, err := os.Stat(p); err == nil && info.Mode()&0111 == 0 {
return fmt.Errorf("precheck: %s lacks exec bit", p)
} Type guard
func hasExecBit(path string) bool {
info, err := os.Stat(path)
return err == nil && info.Mode()&0111 != 0
} Try / catch
if _, err := waveapputil.ResolveGoFmtPath(); err != nil {
if strings.Contains(err.Error(), "not executable") {
// attempt repair: os.Chmod(path, 0755) if the file is owned by the user
}
return err
} Prevention
- Install binaries with 'install -m 755' or extract with permission-preserving tools
- Check for noexec mounts in the Go install location
- After copying binaries between OSes, re-check permission bits
When it happens
Trigger: gofmt exists as a regular file at <goDir>/gofmt but has no +x bits — e.g. copied with cp without -p from a non-executable source, extracted from a zip that lost permission bits, or on a mount with noexec/umask stripping exec bits.
Common situations: Home directory mounted with noexec; archive extraction tool dropped the executable bit; file synced via cloud drive or copied from Windows losing Unix modes; overly restrictive umask during install.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- build failed: %w
- build output is not executable
- failed to create backup directory: %w
- failed to create socket directory: %w
- failed to listen on domain socket: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/a43c78ed9736f9c5.
Report an issue: GitHub.