fnm does not configure `PATH` properly after `su`
Description
I heavily rely on su to switch between users on my machine. One thing I've noticed is that whenever I switch users using su, I get the "Can't create the symlink for multishells" error and I cannot use node within my su process.
kevin@computer $ su testuser
Password:
error: Can't create the symlink for multishells at "/run/user/1000/fnm_multishells/46487_1731361529574". Maybe there are some issues with permissions for the directory? Permission denied (os error 13)
error: Can't create the symlink for multishells at "/run/user/1000/fnm_multishells/46488_1731361529575". Maybe there are some issues with permissions for the directory? Permission denied (os error 13)
testuser@computer $ node
Command 'node' not found, but can be installed with:
apt install nodejs
Please ask your administrator.
testuser@computer $
One thing I've noticed, my kevin user is userid 1000 and my testuser is userid 995. Based on the error messages, it looks like after we're now testuser, it's still trying to write to the directory /run/user/1000/ which includes the userid of my original user. This seems to be the root of the permission issues. I'm guessing that fnm is somehow using some variable that points to the original user, and not the user after the su.
Steps to Reproduce
I am able to confirm this bug on both my regular machines, but given that they might have had some weird configuration I wanted to also test against a fresh VM. I can confirm that the following steps reproduce the bug in a fresh Ubuntu 24.04.1 virtual machine.
- Do a regular install of the OS
- Create a second test user (using
johnin this case), and set the password on the test user (created the user via the gui, set the password viasudo passwd john) - Install curl
sudo apt install curl - Set up user 1:
- Install
fnmvia curl:curl -fsSL https://fnm.vercel.app/install | bash - Configure shell:
source /home/kevin/.bashrc - Install a default version of node
fnm install 20 - Confirm that node is installed and configured
node --version
- Install
- Set up user 2:
- Log out and log into the second user.
- Install
fnmvia curl:curl -fsSL https://fnm.vercel.app/install | bash - Configure shell:
source /home/john/.bashrc - Install a default version of node
fnm install 20 - Confirm that node is installed and configured
node --version
- Switch to user 1 and test:
- Log out and log back in as the original user
- Open a new terminal session and
su john.
Expected
The user is able to switch to a second user without error messages, and fnm and node should be properly configured within the su session.
Actual
After successfully submitting the user's password to su, an error message is printed out:
$ su john
Password:
error: Can't create the symlink for multishells at "/run/user/1000/fnm_multishells/2706_1731363444337". Maybe there are some issues with permissions for the directory? Permission denied (os error 13)
$
Attempting to use node inside the su process fails as the executable cannot be found:
$ node
Command 'node' not found, but can be installed with:
apt install nodejs
Please ask your administrator.
$
Additionally, PATH appears to be misconfigured:
$ echo $PATH
/home/john/.local/share/fnm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
When I check PATH after logging out and logging back in directly, I see an entry that was missing from the path in su: /run/user/1001/fnm_multishells/2560_1731363608152/bin (and since I've logged in as the test user directly, I can successfully start node):
$ echo $PATH
/run/user/1001/fnm_multishells/2560_1731363608152/bin:/home/john/.local/share/fnm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin
Workaround
The main workaround I've been using is using ssh instead of su to get into the other user accounts. ssh does not exhibit this bug so fnm and node is properly configured in the new shell. This is fine, but it means I need to be running an ssh server (which I am doing anyways, but is not ideal) and my muscle memory is for su.
System configuration
Host system (exhibits the bug):
Linux Mint 22 Cinnamon
System Info
System:
Kernel: 6.8.0-48-generic arch: x86_64 bits: 64 compiler: gcc v: 13.2.0 clocksource: tsc
Desktop: Cinnamon v: 6.2.9 tk: GTK v: 3.24.41 wm: Muffin v: 6.2.0 with: docker vt: 7
dm: LightDM v: 1.30.0 Distro: Linux Mint 22 Wilma base: Ubuntu 24.04 noble
Machine:
Type: Desktop Mobo: ASUSTeK model: ROG STRIX B350-F GAMING v: Rev X.0x
serial: <superuser required> part-nu: SKU uuid: <superuser required> UEFI: American Megatrends
v: 6042 date: 04/28/2022
CPU:
Info: 8-core model: AMD Ryzen 7 5800X3D bits: 64 type: MT MCP smt: enabled arch: Zen 3+ rev: 2
cache: L1: 512 KiB L2: 4 MiB L3: 96 MiB
Speed (MHz): avg: 2529 high: 3400 min/max: 2200/4549 boost: enabled cores: 1: 2874 2: 2200
3: 2200 4: 2200 5: 2200 6: 2874 7: 2873 8: 2912 9: 2200 10: 2872 11: 2200 12: 2196 13: 3400
14: 2200 15: 2878 16: 2200 bogomips: 108595
Flags: avx avx2 ht lm nx pae sse sse2 sse3 sse4_1 sse4_2 sse4a ssse3 svm
Virtual machine (also exhibits the bug):
Fresh ubuntu-24.04.1-desktop-amd64.iso (sha256 c2e6f4dc37ac944e2ed507f87c6188dd4d3179bf4a3f9e110d3c88d1f3294bdc)
Related issues:
I did a quick search for the error message Can't create the symlink for multishells and there are a few hits in this repo. I don't think this is a complete dupe of any of the existing issues, but I assume they are related. It's a bit unclear exactly what those other users are doing that causes the issue:
- https://github.com/Schniz/fnm/issues/938. It seems like this user is just getting the error when running as their regular user. Not sure if this is related. There's also a mention of
sudo userwhich isn't a valid command (that would run the commanduseras root, which just gets mesudo: user: command not foundon my machine). Perhaps they meantsu userbut it's not clear.- This issue also has the mention of
/run/user/0which implies userid = 0 which is always root. Perhaps that issue is specifically issues related to runningfnmas root?
- This issue also has the mention of
- https://github.com/Schniz/fnm/issues/1163
- This one seems Mac specific and logs out a separate path (at least a different prefix). In the discussion it seems like
~/.local/stateis sometimes owned by root on Macs, which would explain the permissions error. In my limited experience with Macs, I have seen mac package managers do unusual things so this wouldn't surprise me.
- This one seems Mac specific and logs out a separate path (at least a different prefix). In the discussion it seems like
- https://github.com/Schniz/fnm/issues/1119
- This one references WSL often. It seems like perhaps WSL doesn't set up the
/run/userdirectories as expected (and/or fnm tries to do it's set up before WSL does set up those directories (assuming it does it eventually). I don't have enough experience with WSL to weigh in.
- This one references WSL often. It seems like perhaps WSL doesn't set up the
I've just realized that if I update the fnm section in my .bashrc to the following, it fixes it
# fnm
FNM_PATH="/home/testuser/.local/share/fnm"
if [ -d "$FNM_PATH" ]; then
export PATH="$FNM_PATH:$PATH"
export XDG_RUNTIME_DIR="/run/user/$(id -u $USER)"
eval "`fnm env`"
fi
(this adds this line: export XDG_RUNTIME_DIR="/run/user/$(id -u $USER)")
This ensures the XDG_RUNTIME_DIR env var is configured correctly whenever the shell initializes, including when using su.
in my case it was installed in a different location
# fnm
FNM_PATH="/Users/testuser/.local/share/fnm"
if [ -d "$FNM_PATH" ]; then
export PATH="$FNM_PATH:$PATH"
eval "`fnm env`"
fi
this worked :point_up:
None of the solutions above worked for me. What worked was simply creating the folder:
sudo mkdir -p /run/user/USER_ID/fnm_multishells
and then giving other write permissions to it
sudo chmod -R o+w /run/user/USER_ID