fix hermit `text file busy` issues on linux
Summary
For several months, Linux users have frequently been unable to add STDIO MCP extensions (e.g., extensions using the npx command, etc.). Obviously this is a key functionality and affects a lot of MCP servers!
The goose setup script fails on Linux with a text file busy error. I suspect this is because Hermit tries to self-update its running binary, which Linux locks, unlike macOS. The fix uses a temporary bin/hermit copy on Linux to prevent lock conflicts, redirects activation output to a log file for clean stderr, and skips these changes on macOS to preserve existing behavior.
Type of Change
- [ ] Feature
- [x] Bug fix
- [ ] Refactor / Code quality
- [ ] Performance improvement
- [ ] Documentation
- [ ] Tests
- [ ] Security fix
- [ ] Build / Release
- [ ] Other (specify below)
Testing
I've manually tested this on Linux. I need a macOS user to test these changes. Steps to test on macOS:
- Checkout the PR locally or open it in a codespace. To check out the PR locally, ensure you have the GitHub CLI installed, then run
gh pr checkout 5372in thegoosedirectory. To open the PR in a codespace, view the PR in GitHub and clickCodein the top right of the PR, thenCodespaces > Create codespace on best/fix-hermit-lock. - Disable & enable a STDIO MCP server. You can do this in goose desktop by running
just run-uifrom thegoosedirectory to start the desktop UI, then navigating toExtensionsin the sidebar. Once there, find any MCP server that uses an STDIO command such asnpx, disable it, and enable it again. If you don't see any MCP servers that usenpx, add a new one,npx -y @angiejones/mcp-seleniumfor example. If you see an error, please report it to me! If not, everything should be fine. Play around with goose a bit to make sure. - If you are using a codespace, you will need to test using the goose CLI.
Related Issues
Relates to #2351, #5048, #3030
:warning: This PR is ready for review, but do not merge it. It needs to be tested on macOS.
This issue also affects jbang and uvx scripts. The implementation should only run if Hermit is not installed — inside this block:
# Check if Hermit binary exists and download if not
if [ ! -f ~/.config/goose/mcp-hermit/bin/hermit ]; then
The “text file busy” lock issue occurs only on the first start, when Hermit is not yet installed.
@IA386 Yep I'm aware that is affects uvx STDIO servers as well… haven't tested with jbang but it should resolve issues with it as well.
The “text file busy” lock issue occurs only on the first start, when Hermit is not yet installed.
This is what I thought at first but not what I experienced in my testing, possibly because cleanup doesn't happen properly on failure, and it gets stuck in a “locked” state after that? Not sure.
At least to my understanding of the issue, there’s no cleanup process involved — the binary just dies. Your solution won’t work if someone tries to run it for the first time with a uvx-based MCP or jbang (haven’t seen any MCPs available, but I haven’t really looked either).
So in its current form, this PR doesn’t fully address the issue across different environments unless those scripts are updated as well.
Regarding the implementation — I don’t like that it will execute every time. On a successful install, subsequent runs will still copy an already replaced bin/hermit script.
If I can make a suggestion — please see my comment on #2351. I’m not completely happy with that approach either, but it only triggers once, while the Hermit environment is not yet bootstrapped.
IMHO, the best solution would be to keep the binary with its original name inside the mcp-hermit folder and leave it as is.
Looking forward to a fix on this issue, it is making this unusable in linux.
Nice. Thanks for the revisions on this @The-Best-Codes
Note: After upgrading I had to delete the mcp hermit directory and then it worked: rm -rf ~/.config/goose/mcp-hermit
@rinormaloku Yep :100: I was waiting for the next official release of goose so I could clarify that in the Discord. I should have clarified it here. Thanks!
Thanks for contributing this fix @The-Best-Codes