Skip to content

Conversation

@tennox
Copy link

@tennox tennox commented Dec 11, 2025

Summary

Fix chmod: Operation not permitted error when nix-direnv-reload file is owned by a
different user (e.g., a colleague entered direnv first).

$ direnv allow
direnv: loading /etc/nixos/.envrc
direnv: using flake . --impure --accept-flake-config
chmod: changing permissions of '/etc/nixos/.direnv/bin/nix-direnv-reload': Operation not permitted

Problem

chmod cannot change permissions on a file owned by another user.

Solution

Use install -m 755 /dev/stdin instead of separate cat + chmod. The install command
unlinks and recreates the file rather than modifying it in place, which works even when the
existing file is owned by another user.

Test

Add this to .envrc:

source_url "https://raw.githubusercontent.com/tennox/nix-direnv/fix/chmod-permission-error/direnvrc" \
    "sha256-rXKNtMDtfdKIeU3FnIDmEAyF5NZ3of+Yz2YuU8pYeJI="

…user

Use `install -m 755` instead of separate cat + chmod to atomically
create the file with correct permissions. This works even when an
existing file is owned by another user (e.g., root), as install
unlinks and recreates the file.

Assisted-By: claude-opus-4-5-20251101 via Claude Code
@bbenne10
Copy link
Contributor

Has this fix been tested on Darwin? I worry about its options not matching a nixos or Linux provided binaries.

@tennox
Copy link
Author

tennox commented Dec 12, 2025

Has this fix been tested on Darwin? I worry about its options not matching a nixos or Linux provided binaries.

Good point. I ran some tests and found this to be a darwin-compatible version:

# Good (tested on Linux + macOS)
install -m 755 /dev/stdin "$target" <<'EOF'
...
EOF

Another option would be to just remove the file (did that for devenv) - but I wasn't sure if that would maybe reset other kinds of permissions. (But the file is created by "us" anyways, right? so we could just remove and recreate?)

tennox added a commit to tennox/devenv that referenced this pull request Dec 12, 2025
The previous pipe-based approach (printf | install /dev/stdin) doesn't
work reliably on macOS. Use temp file + install instead, which:
- Preserves exact contents of DEVENV_TASK_ENV (no shell expansion)
- Fixes file-owned-by-another-user problem (install recreates)
- Works on both Linux and macOS

See: nix-community/nix-direnv#647 (comment)

Assisted-By: claude-opus-4-5-20251101 via Claude Code
tennox added a commit to tennox/devenv that referenced this pull request Dec 12, 2025
The pipe-based `echo | install /dev/stdin` approach doesn't work
reliably on macOS (piping to /dev/stdin fails on Darwin).

Simply removing the file first achieves the same result: rm succeeds
on files owned by other users (only needs directory write permission),
then echo + chmod work on the newly created file we own.

See: nix-community/nix-direnv#647 (comment)

Assisted-By: claude-opus-4-5-20251101 via Claude Code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants