GitHub Actions Container Job Volume Permission Denied
A container job cannot write to the mounted workspace because the image runs as a non-root user whose UID does not match the files the runner created, so the bind mount is read-only to that user.
What this error means
Steps inside the container fail with "permission denied" writing to the workspace or a mounted volume, even though the same commands work outside a container.
EACCES: permission denied, open '/__w/repo/repo/dist/out.js'
# the image runs as uid 1001 but the workspace is owned by a different uidCommon causes
Container user UID mismatch
Actions bind-mounts the workspace into the container. If the image default user UID differs from the workspace owner, writes to mounted paths are denied.
Volume owned by root, used by non-root
A named volume or path created as root cannot be written by a non-root container user without adjusting ownership or running as root.
How to fix it
Run the container as the expected user
Set the container to run as root (or the matching UID) so it can write the bind-mounted workspace.
jobs:
build:
runs-on: ubuntu-latest
container:
image: node:20
options: --user rootFix ownership of mounted paths
- chown the workspace or volume to the container user early in the job.
- Build images whose default UID matches the runner workspace owner.
- Use the volumes key with a path the container user can write.
How to prevent it
- Match the container user to the workspace owner, or run as root in CI.
- Adjust ownership of mounted volumes before writing.
- Test container jobs that write to the workspace, not just read.