{"record":{"id":"d0599571879c94fa","repo":"plandex-ai/plandex","slug":"failed-to-apply-update-due-to-permission-error-pl","errorCode":null,"errorMessage":"failed to apply update due to permission error; please try running your command again with 'sudo': %w","messagePattern":"failed to apply update due to permission error; please try running your command again with 'sudo': %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/upgrade.go","lineNumber":150,"sourceCode":"\t}\n\tdefer gzr.Close()\n\n\ttarReader := tar.NewReader(gzr)\n\tfor {\n\t\theader, err := tarReader.Next()\n\t\tif err == io.EOF {\n\t\t\tbreak // End of archive\n\t\t}\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to read tar header: %w\", err)\n\t\t}\n\n\t\t// Check if the current file is the binary\n\t\tif header.Typeflag == tar.TypeReg && (header.Name == \"plandex\" || header.Name == \"plandex.exe\") {\n\t\t\terr = update.Apply(tarReader, update.Options{})\n\t\t\tif err != nil {\n\t\t\t\tif errors.Is(err, fs.ErrPermission) {\n\t\t\t\t\treturn fmt.Errorf(\"failed to apply update due to permission error; please try running your command again with 'sudo': %w\", err)\n\t\t\t\t}\n\t\t\t\treturn fmt.Errorf(\"failed to apply update: %w\", err)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc restartPlandex() {\n\texe, err := os.Executable()\n\tif err != nil {\n\t\tterm.OutputErrorAndExit(\"Failed to determine executable path: %v\", err)\n\t}\n\n\tcmd := exec.Command(exe, os.Args[1:]...)\n\tcmd.Stdin = os.Stdin","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/upgrade.go#L132-L168","documentation":"When the 'plandex' binary is found in the tar, update.Apply (github.com/inconshreveable/go-update) swaps it in place. If that fails specifically with fs.ErrPermission, the CLI returns a dedicated message advising 'sudo'. go-update needs write permission on the installed executable's path (and possibly the containing directory when it renames the file into place).","triggerScenarios":"update.Apply fails with a permission error because the installed plandex binary (e.g. /usr/local/bin/plandex) is owned by root or the user lacks write access to it or its directory.","commonSituations":"plandex was originally installed with sudo into /usr/local/bin; system-managed install paths; non-root user running the self-upgrade.","solutions":["Re-run the upgrade command with sudo: sudo plandex (then accept the upgrade prompt).","Move the binary to a user-writable location, e.g. ~/.local/bin, and update PATH.","chown the binary to your user: sudo chown $(whoami) $(which plandex).","Reinstall via the official install script into a user-owned prefix."],"exampleFix":"// before: user-writable install avoids the error\n$ ls -l /usr/local/bin/plandex  # root-owned, upgrade fails\n// after\n$ sudo chown $(whoami) /usr/local/bin/plandex\n$ # or relocate:\n$ mv /usr/local/bin/plandex ~/.local/bin/ && export PATH=$HOME/.local/bin:$PATH","handlingStrategy":"fallback","validationCode":"exe, _ := os.Executable()\nfi, err := os.Stat(exe)\nif err == nil {\n\tif unix.Access(exe, unix.W_OK) != nil || fi.Mode().Perm()&0200 == 0 {\n\t\tfmt.Println(\"Binary not writable by current user; run with sudo or reinstall to a user-owned path\")\n\t}\n}","typeGuard":null,"tryCatchPattern":"err = update.Apply(tarReader, update.Options{})\nif err != nil {\n\tif errors.Is(err, fs.ErrPermission) {\n\t\tfmt.Println(\"Permission denied replacing binary. Re-run with sudo, or reinstall to ~/.local/bin\")\n\t\treturn\n\t}\n\treturn err\n}","preventionTips":["Install the binary in a user-writable directory (e.g. ~/.local/bin)","Avoid root-owned installs if you plan to self-update","Check writability of os.Executable() before attempting upgrade","Use sudo deliberately for system-path installs"],"tags":["permissions","filesystem","upgrade","sudo"],"backgroundTag":"permission-denied","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}