{"record":{"id":"fbfecaa6abe10051","repo":"pocketbase/pocketbase","slug":"failed-to-rename-the-current-executable-w","errorCode":null,"errorMessage":"failed to rename the current executable: %w","messagePattern":"failed to rename the current executable: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/ghupdate/ghupdate.go","lineNumber":222,"sourceCode":"\toldExec, err := os.Executable()\n\tif err != nil {\n\t\treturn err\n\t}\n\trenamedOldExec := oldExec + \".old\"\n\tdefer os.Remove(renamedOldExec)\n\n\tnewExec := filepath.Join(extractDir, p.config.ArchiveExecutable)\n\tif _, err := os.Stat(newExec); err != nil {\n\t\t// try again with an .exe extension\n\t\tnewExec = newExec + \".exe\"\n\t\tif _, fallbackErr := os.Stat(newExec); fallbackErr != nil {\n\t\t\treturn fmt.Errorf(\"the executable in the extracted path is missing or it is inaccessible: %v, %v\", err, fallbackErr)\n\t\t}\n\t}\n\n\t// rename the current executable\n\tif err := os.Rename(oldExec, renamedOldExec); err != nil {\n\t\treturn fmt.Errorf(\"failed to rename the current executable: %w\", err)\n\t}\n\n\ttryToRevertExecChanges := func() {\n\t\tif revertErr := os.Rename(renamedOldExec, oldExec); revertErr != nil {\n\t\t\tp.app.Logger().Debug(\n\t\t\t\t\"Failed to revert executable\",\n\t\t\t\tslog.String(\"old\", renamedOldExec),\n\t\t\t\tslog.String(\"new\", oldExec),\n\t\t\t\tslog.String(\"error\", revertErr.Error()),\n\t\t\t)\n\t\t}\n\t}\n\n\t// replace with the extracted binary\n\tif err := os.Rename(newExec, oldExec); err != nil {\n\t\ttryToRevertExecChanges()\n\t\treturn fmt.Errorf(\"failed replacing the executable: %w\", err)\n\t}","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/pocketbase/pocketbase/blob/5d217ddb50cb144d80a5d0b0bdf11b52b2c3e457/plugins/ghupdate/ghupdate.go#L204-L240","documentation":"ghupdate: the first step of replacing the running executable — os.Rename(oldExec, oldExec+\".old\") — failed. On this failure nothing has been changed yet (the defer removes the .old name if it exists). Wrapped with %w so the OS-level rename error (permissions, cross-device, text-file-busy equivalents) is preserved.","triggerScenarios":"The running binary's file or its directory is not writable by the process; on Windows the executable may be locked; on Linux a read-only mount or no write permission on the install dir. Note rename stays on one filesystem, so EXDEV is unlikely unless the .old path is redirected.","commonSituations":"Binary installed in /usr/local/bin or /opt owned by root while the app runs unprivileged; container images with the binary on a read-only layer; SELinux denying rename on the exec type.","solutions":["Check the wrapped error for EACCES/EROFS and grant write permission on the binary's directory to the app user","Move the executable to a writable location (e.g. a data volume) before using the updater","On locked/managed hosts, disable ghupdate and update via your package/deploy pipeline"],"exampleFix":"# before\nsudo mv pocketbase /usr/local/bin/ && /usr/local/bin/pocketbase update  # EACCES\n# after\nsudo chown $(whoami) /usr/local/bin/pocketbase  # or place it in a user-writable dir\n./pocketbase update","handlingStrategy":"validation","validationCode":"// ensure the binary's directory is writable before enabling self-update\nexecPath, _ := os.Executable()\nif err := unix.Access(filepath.Dir(execPath), unix.W_OK); err != nil {\n    log.Println(\"self-update disabled: install dir not writable\")\n}","typeGuard":null,"tryCatchPattern":"if err := updater.Update(ctx, false); err != nil {\n    if strings.Contains(err.Error(), \"failed to rename the current executable\") {\n        // EACCES/EROFS: fix dir permissions or relocate binary; nothing was changed yet\n    }\n}","preventionTips":["Install the binary in a directory the runtime user can write to","In containers, update by redeploying the image instead","Check ownership of both the binary and its parent directory"],"tags":["pocketbase","ghupdate","self-update","permissions","rename"],"backgroundTag":null,"analyzedSha":"5d217ddb50cb144d80a5d0b0bdf11b52b2c3e457","analyzedAt":"2026-08-15T10:06:33.165Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}