{"record":{"id":"5277c32f6cd5da61","repo":"henrygd/beszel","slug":"chmod-w","errorCode":null,"errorMessage":"chmod: %w","messagePattern":"chmod: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/tools/fetchsmartctl/main.go","lineNumber":116,"sourceCode":"\t}\n\tif err := f.Close(); err != nil {\n\t\tos.Remove(tmp)\n\t\treturn fmt.Errorf(\"close tmp: %w\", err)\n\t}\n\n\tif hasher != nil && shaHex != \"\" {\n\t\tcleanSha := strings.ToLower(strings.ReplaceAll(strings.TrimSpace(shaHex), \" \", \"\"))\n\t\tgot := strings.ToLower(hex.EncodeToString(hasher.Sum(nil)))\n\t\tif got != cleanSha {\n\t\t\tos.Remove(tmp)\n\t\t\treturn fmt.Errorf(\"hash mismatch: got %s want %s\", got, cleanSha)\n\t\t}\n\t}\n\n\t// Make executable and move into place\n\tif err := os.Chmod(tmp, 0o755); err != nil {\n\t\tos.Remove(tmp)\n\t\treturn fmt.Errorf(\"chmod: %w\", err)\n\t}\n\tif err := os.Rename(tmp, dest); err != nil {\n\t\tos.Remove(tmp)\n\t\treturn fmt.Errorf(\"rename: %w\", err)\n\t}\n\n\tfmt.Println(\"smartctl.exe downloaded to\", dest)\n\treturn nil\n}\n\nfunc fatalf(format string, a ...any) {\n\tfmt.Fprintf(os.Stderr, format+\"\\n\", a...)\n\tos.Exit(1)\n}\n","sourceCodeStart":98,"sourceCodeEnd":131,"githubUrl":"https://github.com/henrygd/beszel/blob/b38fb7dafa60812cc22e6a84ce313e94f1ce0a32/agent/tools/fetchsmartctl/main.go#L98-L131","documentation":"After a successful download, downloadFile chmods the temp file to 0o755 so it can be executed and moved into place. If os.Chmod fails, the error is wrapped as `chmod: %w` and the temp file is removed.","triggerScenarios":"os.Chmod(tmp, 0o755) returns an error: the temp file sits on a filesystem that rejects permission changes (FAT32/exFAT mounts, some network shares, Windows filesystems), or the file was removed between creation and chmod.","commonSituations":"Running the downloader on a Windows filesystem or a USB/network share lacking POSIX perms; TMPDIR redirected to a restrictive mount; antivirus deleting the temp file mid-run.","solutions":["Point TMPDIR (or the destination) at a filesystem supporting POSIX permissions (e.g. Linux ext4 /tmp).","Check mount options of the target filesystem; remount without restrictive fmask/dmask so chmod 0755 is permitted.","Inspect the wrapped underlying error (%w) for the real cause (EACCES, EPERM, ENOENT) and address it directly.","On Windows, chmod is largely unsupported — use a Windows-appropriate install path or skip the chmod."],"exampleFix":"// before\nif err := os.Chmod(tmp, 0o755); err != nil {\n\treturn fmt.Errorf(\"chmod: %w\", err)\n}\n// after\nif runtime.GOOS != \"windows\" {\n\tif err := os.Chmod(tmp, 0o755); err != nil {\n\t\treturn fmt.Errorf(\"chmod: %w\", err)\n\t}\n}","handlingStrategy":"try-catch","validationCode":"// check the temp filesystem supports chmod before downloading\nif fi, err := os.Stat(os.TempDir()); err == nil {\n\t_ = fi // on Windows or vfat mounts, plan to skip chmod\n}","typeGuard":null,"tryCatchPattern":"if err := downloadFile(url, dest, sha); err != nil {\n\tif strings.HasPrefix(err.Error(), \"chmod:\") {\n\t\tlog.Printf(\"chmod failed (filesystem may not support perms): %v\", err)\n\t} else {\n\t\treturn err\n\t}\n}","preventionTips":["Use a temp dir on a POSIX filesystem for downloads.","Skip chmod on windows.GOOS builds.","Inspect the wrapped errno to distinguish EACCES/EPERM/ENOENT.","Keep antivirus from scanning/deleting the temp path."],"tags":["go","filesystem","permissions","chmod"],"backgroundTag":"permission-denied","analyzedSha":"b38fb7dafa60812cc22e6a84ce313e94f1ce0a32","analyzedAt":"2026-08-31T15:10:10.149Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}