`tiup link tiup:<version>` breaks `tiup update --self` and `tiup unlink tiup` leaves TiUP unavailable
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 466
- Forks
- 338
- Avg merge
- 3d 7h
- Merged PRs (30d)
- 8
Description
Bug Report
Please answer these questions before submitting your issue. Thanks!
- What did you do?
After running tiup link tiup:<version>, ~/.tiup/bin/tiup is replaced with a symlink to the selected TiUP component binary.
$ ls -l ~/.tiup/bin/
total 11848
-rw-r--r--. 1 ec2-user ec2-user 7275 May 11 06:18 7b8e153f2e2d0928.root.json
-rw-r--r--. 1 ec2-user ec2-user 7275 May 11 06:58 root.json
-rwxr-xr-x. 1 ec2-user ec2-user 12112056 Apr 10 04:00 tiup
$ tiup link tiup:v1.16.5
package tiup provides these executables: tiup
$ ls -l ~/.tiup/bin/
total 16
-rw-r--r--. 1 ec2-user ec2-user 7275 May 11 06:18 7b8e153f2e2d0928.root.json
-rw-r--r--. 1 ec2-user ec2-user 7275 May 11 06:58 root.json
lrwxrwxrwx. 1 ec2-user ec2-user 49 May 11 06:58 tiup -> /home/ec2-user/.tiup/components/tiup/v1.16.5/tiup
In this state, running tiup update --self fails because TiUP checks whether the actual executed binary path is exactly the same as $TIUP_HOME/bin/tiup.
$ tiup update --self
Tiup install directory is: /home/ec2-user/.tiup/components/tiup/v1.16.5
Error: if you used some external package manager to install TiUP (e.g., brew), try upgrade with that
Additionally, running tiup unlink tiup removes the symlink from ~/.tiup/bin/tiup, but it does not restore the original TiUP binary. As a result, the tiup command itself becomes unavailable unless the user manually copies a TiUP binary back to ~/.tiup/bin/tiup.
$ tiup unlink tiup
/home/ec2-user/.tiup/bin/tiup will be removed.
Do you want to continue? [y/N]:(default=N) y
$ ls -l ~/.tiup/bin/
total 16
-rw-r--r--. 1 ec2-user ec2-user 7275 May 11 06:18 7b8e153f2e2d0928.root.json
-rw-r--r--. 1 ec2-user ec2-user 7275 May 11 06:58 root.json
$ tiup --version
-bash: /home/ec2-user/.tiup/bin/tiup: No such file or directory
This can leave users unable to upgrade TiUP after using the documented tiup link tiup:<version> workflow.
- What did you expect to see?
tiup update --self should either:
- work correctly when
~/.tiup/bin/tiupis a symlink managed bytiup link, or - show a clear message explaining that TiUP is currently linked and how to recover or update it safely.
Also, if tiup unlink tiup is used after linking TiUP itself, I expected one of the following behaviors:
- restore the previous executable binary in ~/.tiup/bin/tiup, or
- print clear recovery instructions before/after removing the symlink.
- What did you see instead?
tiup update --self fails with the following error:
$ tiup update --self
Tiup install directory is: /home/ec2-user/.tiup/components/tiup/v1.16.5
Error: if you used some external package manager to install TiUP (e.g., brew), try upgrade with that
After that, running:
$ tiup unlink tiup
removes ~/.tiup/bin/tiup, but does not restore the original binary. Therefore, tiup is no longer available from the normal command path.
The user can recover manually by copying a binary such as:
cp ~/.tiup/components/tiup/<version>/tiup ~/.tiup/bin/tiup
However, this recovery step does not seem to be documented or suggested by the command output.
Possible fixes
- Make
tiup update --selfhandle TiUP-managed symlinks correctly- For example, by resolving symlinks before comparing the expected TiUP binary path with the actual executable path.
- When
tiup link tiup:<version>replaces~/.tiup/bin/tiup, keep a backup of the original binary and restore it automatically ontiup unlink tiup. - If the current behavior is intentional, document the limitation clearly and show recovery steps, such as copying a TiUP binary from
~/.tiup/components/tiup/<version>/tiupback to~/.tiup/bin/tiup. - Improve the error message from
tiup update --selfso that it mentions thetiup link tiup:<version>case instead of only suggesting external package managers.
- What version of TiUP are you using (
tiup --version)?
$ tiup --version
1.16.5 v1.16.5
Go Version: go1.25.0
Git Ref: master
GitHash: 9bdae0450713fe1b69b0d1a388ad4908276b1f98
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the implementations of tiup link, tiup unlink, and tiup update --self, then reproduce the commands with ~/.tiup/bin/tiup linked to a component binary. Trace how the executable path is checked and how the link is removed. Done means the linked workflow either updates safely or explains recovery, and unlinking does not leave TiUP unavailable.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100