pingcap / pingcap/tiup

`tiup link tiup:<version>` breaks `tiup update --self` and `tiup unlink tiup` leaves TiUP unavailable

Open
#2,706 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type/bug
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!

  1. 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.

  1. What did you expect to see?

tiup update --self should either:

  • work correctly when ~/.tiup/bin/tiup is a symlink managed by tiup 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.
  1. 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 --self handle 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 on tiup 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>/tiup back to ~/.tiup/bin/tiup.
  • Improve the error message from tiup update --self so that it mentions the tiup link tiup:<version> case instead of only suggesting external package managers.
  1. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.