Skip to content

create fails with "Permission denied (os error 13)" on read-only files that carry xattrs #21

Description

@sdrshn-nmbr

Summary

rift create aborts on any tree containing a file that is both mode 444 and carries an extended attribute. git creates loose objects and pack files read-only, and macOS tags files with com.apple.provenance. Any repo that has run git gc, or that vendors a git repo, e.g. under .terraform/modules/, will hit it.

The workspace is rolled back on failure, so nothing is left behind to inspect.

Reproduction

mkdir -p src && cd src
git init -q && echo hi > a.txt
xattr -w com.apple.test 1 a.txt
chmod 444 a.txt

rift init && rift create --name probe
# Permission denied (os error 13)

Remove either condition and it succeeds — chmod u+w a.txt, or xattr -c a.txt.

Cause

The per-file copy order is: write contents → apply source mode → copy xattrs. Once the mode is 444, setxattr on the destination returns EACCES for non-root, because setting an xattr requires the write bit.

sudo fs_usage -w -f filesys rift, errno in brackets:

setxattr [ 13]  .../workspace/.../objects/pack/pack-<sha>.rev
unlinkat        ...                     # recursive rollback begins
exit     [  1]

sudo rift create succeeds, since root bypasses the permission check.

Suggested fix

Copy xattrs before applying the mode, or apply the mode last. Either is a reordering and preserves fidelity. Alternatively, treat EACCES from setxattr as a warning rather than fatal.

Smaller thing: error context

The error comes through as a bare Permission denied (os error 13) and has no path or operation attached, and RiftError.path is undefined via the FFI, so I ended up reaching for a syscall trace to find which file it was.

Including the path and operation (something like setxattr /path/to/file: Permission denied (os error 13)) would probably save some time. Or a --verbose flag would do the job just as well. Happy to send a PR if it'd be useful!

Environment

  • rift-snapshot 0.0.10 — CLI and bun FFI fail identically
  • macOS 26 (Darwin 25.5.0), arm64, APFS

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions