{"record":{"id":"1102880be6159b72","repo":"matryer/xbar","slug":"create-temp-file","errorCode":null,"errorMessage":"create temp file","messagePattern":"create temp file","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/update/update.go","lineNumber":196,"sourceCode":"}\n\nfunc (u *Updater) downloadAndReplaceApp(asset Asset) error {\n\tfilename := path.Base(asset.BrowserDownloadURL)\n\tswitch {\n\tcase strings.HasSuffix(filename, \".zip\"):\n\t\t// fine\n\tdefault:\n\t\treturn errors.Errorf(\"file not supported: %s\", filename)\n\t}\n\tresp, err := u.Client.Get(asset.BrowserDownloadURL)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"download asset\")\n\t}\n\tdefer resp.Body.Close()\n\tconst defaultTempDir = \"\"\n\tf, err := os.CreateTemp(defaultTempDir, \"*-\"+filename)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"create temp file\")\n\t}\n\t_, err = io.Copy(f, io.LimitReader(resp.Body, u.DownloadBytesLimit))\n\tif err != nil {\n\t\tf.Close()\n\t\treturn errors.Wrap(err, \"download asset\")\n\t}\n\tf.Close()\n\texecutable, err := u.GetExecutable()\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"get executable\")\n\t}\n\tappPath, err := appPathFromExecutable(executable)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"find app path\")\n\t}\n\tappPathDir := filepath.Dir(appPath)\n\tappPreviousPath := appPath + \".previous\"\n\terr = os.Rename(appPath, appPreviousPath)","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/matryer/xbar/blob/d624239058997c80118eaebe2e7f8331b3c765e0/pkg/update/update.go#L178-L214","documentation":"os.CreateTemp failed while creating a temporary file to hold the downloaded zip; the error is wrapped as 'create temp file'. CreateTemp uses the default temp directory (empty dir string) and a pattern of '*-'+filename.","triggerScenarios":"Calling Update() when the temp directory is not writable, doesn't exist, has no space/inodes left, or the filename contains characters invalid for a temp file pattern on the OS.","commonSituations":"TMPDIR set to a non-existent or read-only path; read-only container filesystem or full disk; asset filename with path separators or illegal characters (e.g. ':' on Windows) breaking the temp pattern.","solutions":["Check disk space and that the OS temp dir (TMPDIR/TMP) exists and is writable.","Sanitize the asset filename (strip path separators/illegal chars) before using it in the temp pattern.","Point the process at a writable temp directory via TMPDIR.","Fall back to os.CreateTemp(\"\", \"update-*\") ignoring the remote filename."],"exampleFix":"// before\nf, err := os.CreateTemp(defaultTempDir, \"*-\"+filename)\n// after\nf, err := os.CreateTemp(\"\", \"app-update-*.zip\")","handlingStrategy":"validation","validationCode":"tmp := os.TempDir()\nif fi, err := os.Stat(tmp); err != nil || !fi.IsDir() {\n\treturn fmt.Errorf(\"temp dir %s unavailable: %v\", tmp, err)\n}\nprobe, err := os.CreateTemp(tmp, \"probe-*\")\nif err != nil {\n\treturn fmt.Errorf(\"temp dir not writable: %w\", err)\n}\nprobe.Close(); os.Remove(probe.Name())","typeGuard":null,"tryCatchPattern":"err := u.Update()\nif err != nil && strings.Contains(err.Error(), \"create temp file\") {\n\tos.Setenv(\"TMPDIR\", \"/var/tmp\") // or a known-writable dir\n\terr = u.Update()\n}","preventionTips":["Keep TMPDIR pointing at an existing, writable directory","Monitor disk space/inodes on temp volumes","Sanitize release asset filenames before they're used in file paths"],"tags":["filesystem","temp-file","permissions"],"backgroundTag":"temp-file-creation-failed","analyzedSha":"d624239058997c80118eaebe2e7f8331b3c765e0","analyzedAt":"2026-09-02T22:38:22.007Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}