{"record":{"id":"220f6d3d9d52c312","repo":"henrygd/beszel","slug":"create-dir-w","errorCode":null,"errorMessage":"create dir: %w","messagePattern":"create dir: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/tools/fetchsmartctl/main.go","lineNumber":47,"sourceCode":"\t\tfatalf(\"-url and -out are required\")\n\t}\n\n\tif !*force {\n\t\tif info, err := os.Stat(*out); err == nil && info.Size() > 0 {\n\t\t\tfmt.Println(\"smartctl.exe already present, skipping download\")\n\t\t\treturn\n\t\t}\n\t}\n\n\tif err := downloadFile(*url, *out, *sha); err != nil {\n\t\tfatalf(\"download failed: %v\", err)\n\t}\n}\n\nfunc downloadFile(url, dest, shaHex string) error {\n\t// Prepare destination\n\tif err := os.MkdirAll(filepath.Dir(dest), 0o755); err != nil {\n\t\treturn fmt.Errorf(\"create dir: %w\", err)\n\t}\n\n\t// HTTP client\n\tclient := &http.Client{Timeout: 60 * time.Second}\n\treq, err := http.NewRequest(http.MethodGet, url, nil)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"new request: %w\", err)\n\t}\n\treq.Header.Set(\"User-Agent\", \"beszel-fetchsmartctl/1.0\")\n\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"http get: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode < 200 || resp.StatusCode >= 300 {\n\t\treturn fmt.Errorf(\"unexpected HTTP status: %s\", resp.Status)","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/henrygd/beszel/blob/b38fb7dafa60812cc22e6a84ce313e94f1ce0a32/agent/tools/fetchsmartctl/main.go#L29-L65","documentation":"Thrown by downloadFile in the fetchsmartctl build tool when os.MkdirAll fails to create the parent directory of the download destination. It is a wrapped OS error from the codegen/update tool that fetches smartmontools binaries. The download aborts before any HTTP request is made.","triggerScenarios":"Running the fetchsmartctl tool (go generate / go run) and the destination's parent directory cannot be created or accessed.","commonSituations":"Output path (-o flag or default) points to a read-only source tree; typo'd path segment collides with an existing regular file; running without write permission in repo dir; disk full.","solutions":["Check the wrapped %w OS error for the exact cause","Verify the destination path's parent is not an existing file and is writable","Run the tool from a writable checkout (not read-only CI volume) and free disk space if needed","Create the directory manually and re-run to isolate permissions"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"parent := filepath.Dir(dest)\nif info, err := os.Stat(parent); err == nil && !info.IsDir() {\n\treturn fmt.Errorf(\"%s exists and is not a directory\", parent)\n}\nif err := os.MkdirAll(parent, 0o755); err != nil {\n\treturn err\n}","typeGuard":null,"tryCatchPattern":"if err := downloadFile(url, dest, sha); err != nil {\n\tvar perr *fs.PathError\n\tif errors.As(err, &perr) && perr.Op == \"mkdir\" {\n\t\tfmt.Printf(\"fix permissions on %s: %v\\n\", filepath.Dir(dest), perr.Err)\n\t}\n\tos.Exit(1)\n}","preventionTips":["Run codegen tools from a writable checkout","Never point -o/dest at a path whose parent is a regular file","Check disk space in CI before running fetch tools","Avoid read-only mounts for generated assets"],"tags":["filesystem","build-tool","download"],"backgroundTag":"temp-directory-not-writable","analyzedSha":"b38fb7dafa60812cc22e6a84ce313e94f1ce0a32","analyzedAt":"2026-08-31T15:10:10.149Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}