wavetermdev/waveterm · error
gofmt path is a directory: %s
Error message
gofmt path is a directory: %s
What it means
ResolveGoFmtPath guards against misconfiguration by rejecting a gofmt path that exists but is a directory rather than an executable file, returning 'gofmt path is a directory: %s'. This prevents exec.Command from failing later with a confusing 'permission denied' or 'is a directory' error.
Source
Thrown at pkg/waveapputil/waveapputil.go:55
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
}
cmd := exec.Command(gofmtPath)
cmd.Stdin = bytes.NewReader(contents)
formattedOutput, err := cmd.Output()View on GitHub (pinned to a4447c1563)
Solutions
- Remove or rename the directory at the reported path so a real gofmt file can live there
- Extract/install the gofmt binary file directly into the Go bin directory
- Correct TsunamiGoPath so it points to the go executable, not a directory root
- Verify with 'file <path>/gofmt' that it is an executable, not a directory
Example fix
// before # ls $GOBIN/gofmt -> directory (extracted archive) // after # rm -rf $GOBIN/gofmt # cp $(go env GOROOT)/bin/gofmt $GOBIN/gofmt
Defensive patterns
Strategy: validation
Validate before calling
p, err := waveapputil.ResolveGoFmtPath()
if err != nil { return err }
info, _ := os.Stat(p)
if info.IsDir() { return fmt.Errorf("%s is a directory", p) } Type guard
func isExecutableFile(path string) bool {
info, err := os.Stat(path)
return err == nil && info.Mode().IsRegular()
} Try / catch
if _, err := waveapputil.ResolveGoFmtPath(); err != nil {
if strings.Contains(err.Error(), "is a directory") {
log.Printf("misconfigured toolchain: %v", err)
}
return err
} Prevention
- Extract toolchain archives into the bin dir, not into a subfolder named after the binary
- Point TsunamiGoPath at the go executable, never at a directory
- Inspect the Go bin dir after manual installs
When it happens
Trigger: os.Stat on <goDir>/gofmt succeeds and info.IsDir() is true — e.g. TsunamiGoPath points to a directory whose sibling layout makes gofmt resolve to a directory, or someone created a folder named 'gofmt' in the Go bin directory.
Common situations: A user created a 'gofmt' directory (e.g. extracted an archive into bin/gofmt/ instead of bin/); TsunamiGoPath misconfigured so filepath.Dir resolves oddly; a mount point named gofmt.
Related errors
- wcloud endpoint not set
- wcloud ping endpoint not set
- API type mismatch: chat has %s, chatOpts has %s
- model mismatch: chat has %s, chatOpts has %s
- API version mismatch: chat has %s, chatOpts has %s
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/2b6b3c513584713e.
Report an issue: GitHub.