[Cowork] Cannot git push to GitHub from sandbox (proxy 403); .git/index.lock strands after commits

Resolved 💬 1 comment Opened May 5, 2026 by ckinkead-sayari Closed Jun 2, 2026

Summary

Two structural git workflow failures inside the Cowork sandbox on macOS. Both reproducible across many sessions, neither resolvable from inside the sandbox.

Issue 1: git push blocked by outbound proxy

Every git push and git pull from inside Cowork returns:

remote: Received HTTP code 403 from proxy after CONNECT
fatal: unable to access 'https://github.com/...': Received HTTP code 403 from proxy after CONNECT

The same remote URL with the same credentials pushes successfully from the host (outside Cowork). Credentials are valid — git ls-remote from host succeeds against the same URL. Differential is the network path, not auth.

No in-sandbox workaround exists:

  • gh CLI not present (and would route through the same proxy)
  • WebFetch can reach github.com HTML but git protocol needs CONNECT
  • No alternate push path exposed

Issue 2: .git/index.lock stranded after commits

After git commit from inside Cowork, .git/index.lock (and sometimes HEAD.lock) is left as an empty 0-byte file. From inside the sandbox:

$ rm -f .git/index.lock
rm: cannot remove '.git/index.lock': Operation not permitted

Note: the error is EPERM, not the usual file in use. chmod 777 does not change this — virtiofs is enforcing a permission rule the sandbox cannot override.

lsof from the host shows com.apple.Virtualization.VirtualMachine holding a read-only fd on the lock file:

com.apple.Virtualization.VirtualMachine <pid> <user> <fd>r REG ... .git/index.lock

The two facts (EPERM in sandbox + read-only host fd) are reliably correlated, but the exact mechanism (virtiofs permission policy vs. fd-keepalive vs. something else) isn't pinned down.

The user-side workaround built — a host-side launchd agent (StartInterval=10) that parses lsof -F pca to identify Virtualization.framework + read-only as ghost holders and force-unlinks them from the host — works, but:

  1. Adds 10s polling latency. Sandbox retries during that window still fail.
  2. Requires every Cowork user to install a host-side LaunchAgent scoped to their repo. Not portable.
  3. The fix has to live outside the sandbox because the sandbox lacks unlink permission.

Sample reaper output during a single commit cycle:

{"action":"reaped_ghost","lock":"index.lock","lock_age_seconds":7}
{"action":"reaped_ghost","lock":"HEAD.lock","lock_age_seconds":3}
{"action":"reaped_ghost","lock":"index.lock","lock_age_seconds":2}

Why this matters

Standard session-end protocols (commit + push) hit both failure modes. The push always fails; users have to remember to push from host later. The lock thrashes mid-commit when reaper timing is unlucky. After a productive Cowork session, users frequently have stuck commits on their host they didn't realize were stuck — discovered only via git log origin/main..HEAD in a later session.

Asks (easiest first)

  1. Allowlist CONNECT to github.com:443 in the Cowork outbound proxy. Likely a config change. Resolves Issue 1 entirely. Probably the highest-impact single fix.
  2. Document the proxy limitation in Cowork onboarding. Today the failure is silent. Trivial change, saves hours of diagnostic work per affected user.
  3. Surface a UX hint when sandbox detects a git push 403 — direct user to push-from-host until the proxy fix lands.
  4. Investigate the virtiofs EPERM-on-unlink behavior for files held read-only by the host VM. Resolves Issue 1 at source and removes the need for users to install host-side reapers.

Environment

  • macOS (Apple Silicon)
  • Claude Code Desktop + Cowork sandbox
  • Virtiofs-mounted shared host directory
  • Sessions affected: 10+ over several weeks; both failure modes still active in current session

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗