{"record":{"id":"5fa35397796c21af","repo":"wavetermdev/waveterm","slug":"file-is-not-a-go-file-s","errorCode":null,"errorMessage":"file is not a Go file: %s","messagePattern":"file is not a Go file: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/waveappstore/waveappstore.go","lineNumber":425,"sourceCode":"}\n\nfunc FormatGoFile(appId string, fileName string) error {\n\tif err := ValidateAppId(appId); err != nil {\n\t\treturn fmt.Errorf(\"invalid appId: %w\", err)\n\t}\n\n\tappDir, err := GetAppDir(appId)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfilePath, err := validateAndResolveFilePath(appDir, fileName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif filepath.Ext(filePath) != \".go\" {\n\t\treturn fmt.Errorf(\"file is not a Go file: %s\", fileName)\n\t}\n\n\tgofmtPath, err := waveapputil.ResolveGoFmtPath()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to resolve gofmt path: %w\", err)\n\t}\n\n\tcmd := exec.Command(gofmtPath, \"-w\", filePath)\n\tif output, err := cmd.CombinedOutput(); err != nil {\n\t\treturn fmt.Errorf(\"gofmt failed: %w\\nOutput: %s\", err, string(output))\n\t}\n\n\treturn nil\n}\n\nfunc ListAllAppFiles(appId string) (*fileutil.ReadDirResult, error) {\n\tif err := ValidateAppId(appId); err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid appId: %w\", err)","sourceCodeStart":407,"sourceCodeEnd":443,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/waveappstore/waveappstore.go#L407-L443","documentation":"FormatGoFile only formats Go source; after resolving the file path inside the app directory it checks filepath.Ext(filePath) == \".go\". If the requested file has any other extension, it returns \"file is not a Go file\" with the original fileName. This guards gofmt from being run on non-Go files.","triggerScenarios":"Calling FormatGoFile on e.g. \"manifest.json\", \"index.tsx\", \"style.css\", or any file without a \".go\" extension within the app directory.","commonSituations":"A generic \"format this file\" frontend action routed to the Go formatter regardless of file type; user opens a README and hits format; case-sensitivity issue where the file is named \"MAIN.GO\" — actually .GO uppercase also fails since Ext comparison is case-sensitive on Linux.","solutions":["Only call FormatGoFile for files ending in \".go\"; route other file types to their own formatters (prettier, etc.)","Check strings.HasSuffix(fileName, \".go\") in the caller before invoking","If the file genuinely is Go source, rename it to have a .go extension first (RenameAppFile)","Handle the error gracefully in UI by disabling the format action for non-Go files"],"exampleFix":"// before\nFormatGoFile(appId, fileName)\n// after\nif strings.HasSuffix(fileName, \".go\") {\n    FormatGoFile(appId, fileName)\n}","handlingStrategy":"validation","validationCode":"if !strings.HasSuffix(fileName, \".go\") {\n\treturn fmt.Errorf(\"%s is not a Go file; use the appropriate formatter\", fileName)\n}","typeGuard":"func isGoFile(name string) bool { return strings.HasSuffix(strings.ToLower(name), \".go\") }","tryCatchPattern":"if err := FormatGoFile(appId, fileName); err != nil {\n\tif strings.Contains(err.Error(), \"file is not a Go file\") {\n\t\treturn nil // skip formatting for non-Go files\n\t}\n\treturn err\n}","preventionTips":["Route format requests to formatters by file extension (.go -> gofmt, .ts/.tsx -> prettier, etc.)","Check the extension before enabling the format action in UI","Remember the check is extension-based: a Go file must end in .go to be formattable"],"tags":["validation","gofmt","file-type"],"backgroundTag":"unsupported-file-type","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}