[macOS][Codex App][File Provider] Restored OneDrive workspaces get System Policy EPERM after cold relaunch despite valid grants

Open 💬 6 comments Opened Jul 13, 2026 by dianshili

What version of the Codex App are you using (From “About Codex” dialog)?

26.707.62119 (5211); bundled codex-cli 0.144.2

What subscription do you have?

ChatGPT Pro

What platform is your computer?

macOS Tahoe 26.5.2 (25F84); Darwin 25.5.0 arm64 arm; Apple Silicon

What issue are you seeing?

Summary

After signing out, fully quitting, and cold-relaunching Codex Desktop (installed here as ChatGPT.app; bundle com.openai.codex), previously selected OneDrive/File Provider workspaces can become unreadable to restored background Git workers and to later shell, Git, Node.js, and Python processes.

The paths still exist and metadata checks may succeed, but real directory access fails with EPERM / Operation not permitted even though Full Disk Access and the OneDrive File Provider domain grant for com.openai.codex remain allowed.

Representative errors:

Operation not permitted
EPERM: operation not permitted, scandir
PermissionError: [Errno 1] Operation not permitted
fatal: Unable to read current working directory: Operation not permitted

This is best classified as a Codex Desktop × macOS OneDrive File Provider interoperability defect. The evidence points primarily to Desktop workspace-lifecycle and child-process spawning behavior, but a provider-side interaction has not been eliminated.

The account switch is not the direct permission cause: on the reproduced cold launch, the first Git denial occurred about 69.4 seconds before authentication of the newly selected account completed. In this reproduction, the logout/relogin workflow was accompanied by a full quit and cold relaunch. The evidence implicates that process-lifecycle transition, not the identity of the newly authenticated account.

Impact

Once the state occurs, every task rooted in the affected OneDrive workspace is blocked. This includes workspace initialization, Git discovery, pwd/ls, Git, Node.js fs.readdir*, Python os.listdir, and tools whose startup working directory is inside the workspace.

Because the Desktop app restores multiple saved workspace roots, a single cold launch can generate a large burst of background Git denials across several workspaces before the user opens a task.

Established observations

  • The selected workspace is a direct workspace under a OneDrive File Provider root, not merely an indirect writable_roots entry.
  • Full Disk Access for com.openai.codex remained allowed.
  • The TCC FileProviderDomain grant for com.openai.codex and com.microsoft.OneDrive-mac.FileProvider/OneDrive remained allowed.
  • The installed app's bundle/code-signing identity matched the client identity recorded in those grants.
  • The relevant TCC rows were not revoked or changed during the reproduction window.
  • The app is not App Sandbox-enabled; the failure is still reported as a macOS System Policy denial.
  • ls, Git, Node.js, and Python all fail against the same OneDrive directory.
  • Equivalent probes succeed in /private/tmp and a normal local directory. An iCloud Drive control path also succeeded on this machine.
  • A probe launched outside the Codex workspace Seatbelt profile still fails against the OneDrive path. The Codex workspace sandbox is therefore not a sufficient explanation.
  • The failure persists when OneDrive and its File Provider extension are running.
  • A prior OneDrive update/provider restart temporarily coincided with recovery in an already-running Desktop process. The mechanism of that temporary recovery is unknown; a later cold-relaunch failure did not recover after an ordinary Desktop restart.
  • The kernel emits System Policy deny(1) file-read-data, which makes POSIX mode bits/ACLs an insufficient or unlikely explanation.

Normalized from the sanitized unified log:

(Sandbox) System Policy: git(<pid>) deny(1) file-read-data \
/Users/<user>/Library/CloudStorage/OneDrive-<tenant>/<test-workspace>/<redacted>

Apple's macOS filesystem guidance explains that EPERM can reflect sandbox/MAC enforcement and that MAC attribution depends on identifying the responsible code; unusual child behavior such as daemonization can break that relationship:

https://developer.apple.com/forums/thread/678819

Relative causal timeline

T+0 is the cold Desktop launch after logout and full application exit.

| Relative time | Observed event |
|---|---|
| T+0.000s | LaunchServices starts the new Desktop process |
| T+2.269s | New bundled app-server records its first event |
| T+4.927s | First large burst of Git System Policy deny file-read-data events |
| T+74.346s | Authentication of the newly selected account completes |
| T+77.346s | New local authentication state is written |
| T+118.772s | A later bundled Codex process is denied in the OneDrive tree |
| T+~229s | Read-only shell, Git, Node.js, and Python probes confirm persistent failure |

The ordering is the important point: the initial denial predates new-account authentication by approximately 69.419s.

What steps can reproduce the bug?

Preconditions

  1. Select a directory inside the OneDrive File Provider tree directly as a Codex Desktop workspace.
  2. Keep at least one Git repository in a saved OneDrive workspace.
  3. Confirm that the currently running Desktop process can initially read the workspace.
  4. Confirm that Codex Desktop has its normal macOS file permissions. In this reproduction, both Full Disk Access and the OneDrive File Provider domain grant were allowed.

Steps

  1. Open Codex Desktop with the OneDrive workspace selected.
  2. Sign out of the current ChatGPT account.
  3. Fully quit Codex Desktop and wait for its existing processes to exit.
  4. Cold-launch Codex Desktop.
  5. Temporarily leave authentication incomplete while the app restores saved workspace roots and begins background Git discovery.
  6. Complete authentication.
  7. Open a task rooted in the restored OneDrive workspace.
  8. Run the following read-only probe.
#!/bin/zsh
# Read-only reproduction probe. It performs no writes.

set -u
ROOT="${1:?Usage: $0 /absolute/path/to/workspace}"

run_probe() {
  printf '\n[%s]\n' "$1"
  shift
  "$@"
  local rc=$?
  printf 'exit=%d\n' "$rc"
  return 0
}

run_probe stat /usr/bin/stat -f '%N %Sp' "$ROOT"
run_probe ls /bin/ls -la "$ROOT"
run_probe pwd /bin/zsh -c 'cd "$1" && /bin/pwd -P' _ "$ROOT"
run_probe node node -e \
  'const fs=require("fs"); console.log(fs.readdirSync(process.argv[1]).length)' \
  "$ROOT"
run_probe python python3 -c \
  'import os,sys; print(len(os.listdir(sys.argv[1])))' \
  "$ROOT"
run_probe git /usr/bin/env GIT_OPTIONAL_LOCKS=0 \
  git -c core.fsmonitor=false -C "$ROOT" \
  rev-parse --is-inside-work-tree

Actual result

The metadata-oriented stat may succeed, while cd/pwd, ls, Node.js, Python, and Git fail with EPERM or equivalent Operation not permitted errors.

Control result

The same tool families succeed against /private/tmp and a normal local directory from the same Desktop lifecycle. This is not a general inability of the app to execute those tools.

What is the expected behavior?

A workspace explicitly selected by the user and still authorized for Codex Desktop should remain readable after logout and a cold application restart.

If usable File Provider access cannot be restored, the app should validate access before launching background Git discovery, stop scanning that root after EPERM, and present one actionable “Reauthorize/reselect workspace” flow. It should not repeatedly launch workers against a directory that macOS will deny.

Additional information

Read-only implementation audit

The installed production bundle at /Applications/ChatGPT.app/Contents/Resources/app.asar was inspected read-only. The following are normalized descriptions of generated/minified behavior, not claims about stable source symbols.

Restored workspace lifecycle

The observed Desktop flow persists saved workspace roots as path strings. Folder selection and restoration are effectively handled as:

selected file path -> stat/path resolution -> saved root -> background scan

I did not find an actual directory-enumeration gate before restored-root Git discovery, a File Provider lifecycle revalidation path, or an explicit EPERM recovery flow in this build. A path existing or passing stat() is not proof that a new process lifecycle can enumerate it.

Closed Desktop Git-worker path

The packaged Desktop Git wrapper has a normalized call shape equivalent to:

gitExecutor(command, {
  cwd: workspace,
  killProcessTree: true
});

The local process host maps this on macOS to a spawn equivalent to:

spawn(command, args, {
  cwd: workspace,
  detached: true
});

Node documents that on non-Windows platforms detached: true makes the child the leader of a new process group and session:

https://nodejs.org/api/child_process.html#optionsdetached

This is a plausible Desktop path consistent with the first background Git denial burst. It is not proven to be the unique cause without a same-signature A/B build.

Open-source bundled Codex path

Bundled Codex 0.144.2 contains a separate new-session path for later shell/pipe/snapshot children:

The relevant open-source change was merged in PR #9477:

https://github.com/openai/codex/pull/9477

This is a candidate mechanism for later interactive/non-TTY child failures, not a proven regression. It must not be conflated with the closed Desktop worker that can launch the initial cold-start Git scan before an interactive shell command runs.

Leading hypotheses requiring a signed A/B build

Two mechanisms may be independent or interacting:

  1. Restored File Provider access is stale or not revalidated. The new Desktop lifecycle restores raw paths and begins background work before verifying a real open/readdir from both the parent and worker context.
  2. New-session child isolation changes macOS responsibility attribution. Desktop detached:true and bundled Codex setsid() may prevent File Provider/MAC access from being attributed to the already authorized app.

A OneDrive/File Provider interaction may also participate. The current evidence does not justify assigning sole responsibility to either OpenAI, Microsoft, or macOS at the single-line level.

Requested signed A/B experiment

Please test builds with the same OpenAI signature, bundle identifier, entitlements, and unchanged TCC state:

| Build | Desktop Git worker | Bundled Codex child |
|---|---|---|
| A | current new session (detached:true) | current setsid() |
| B | inherit parent session | current setsid() |
| C | current detached:true | same session/new process group, or no detach for diagnosis |
| D | inherit parent session | same session/new process group, or no detach for diagnosis |

For each build, compare:

  • restored raw path followed immediately by background scanning; and
  • restored path followed by a real parent-and-child directory probe, with an appropriate reauthorization/reselection flow if that probe returns EPERM.

Suggested privacy-preserving instrumentation: build number, random test-run ID, PID/PPID/PGID/session relationship, executable identity, provider class, probe stage, errno, and whether the child session matches the parent. Do not log paths, filenames, directory entries, account names, emails, Git remotes, or document content.

<details>
<summary>Diagnostic A/B sketches — not production patches and not run on the affected Mac</summary>

These sketches are provided only to help OpenAI build a signed causal test. They have not been compiled or executed on the reporter's Mac. They are not user-side workarounds. Modifying/re-signing the installed app would change the code-signing/TCC conditions and invalidate the experiment.

Desktop worker diagnostic flag

 const child = spawn(command, args, {
   cwd,
-  detached: killProcessTree,
+  detached:
+    killProcessTree &&
+    !(
+      process.platform === "darwin" &&
+      featureFlags.fileProviderResponsibleCodeAB === "inherit-session"
+    ),
 });

This deliberately trades away current process-tree cleanup behavior in the diagnostic variant; it is not suitable for release. A production design must preserve cancellation and descendant cleanup, potentially with a signed native/Rust supervisor that uses a new process group without creating a new session, after validating that design with macOS TCC/File Provider.

Bundled Codex diagnostic policy

Conceptually, route all current non-TTY setsid() call sites through an internal policy selected by the signed build:

enum NonTtyIsolation {
    NewSession,      // current setsid() behavior
    NewProcessGroup, // diagnostic: setpgid(0, 0), same session
}

fn isolate_child(mode: NonTtyIsolation) -> std::io::Result<()> {
    match mode {
        NonTtyIsolation::NewSession => detach_from_tty(),
        NonTtyIsolation::NewProcessGroup => set_process_group(),
    }
}

Resolve the flag before entering pre_exec; do not parse environment variables, allocate, log, or take locks inside pre_exec. Apply the policy consistently to spawn.rs, pipe.rs, and shell_snapshot.rs. Preserve tests for both session modes and verify that killpg() terminates children and grandchildren without orphans.

Workspace validation gate

// Illustrative pseudocode.
async function activateRestoredWorkspace(root: string) {
  try {
    await enumerateAtMostOneEntryWithoutLogging(root);
    await processSupervisor.probeDirectoryWithoutLogging(root);
  } catch (error) {
    if (error?.code === "EPERM" || error?.code === "EACCES") {
      suspendBackgroundScans(root);
      markWorkspaceAuthorizationRequired(root);
      presentOneReselectOrReauthorizeAction(root);
      return;
    }
    throw error;
  }

  scheduleGitDiscovery(root);
}

Do not hard-code OneDrive-* path matching. Use the platform mechanism appropriate to this distribution to classify/revalidate File Provider access. Security-scoped bookmarks should not be assumed mandatory for the current non-App-Sandbox build without further platform validation.

Minimum regression assertions

  • Authorized local, OneDrive, and iCloud workspaces survive cold restart and logout/relogin.
  • No Git scan begins until parent and worker directory probes pass.
  • A stopped provider produces a bounded unavailable state, not a retry storm.
  • EPERM produces one actionable reauthorization/reselection prompt.
  • Same-session/new-process-group mode preserves process-tree cancellation with no orphaned helpers.
  • Interactive CLI job control and PTY behavior do not regress.
  • Diagnostic telemetry contains no user paths, filenames, account identifiers, emails, remotes, or directory entries.

</details>

Related report, not a duplicate

Issue #16179 reports a closely related iCloud/File Provider Operation not permitted case despite Full Disk Access:

https://github.com/openai/codex/issues/16179

It is not the same reproduction: #16179 fails for an indirect iCloud writable_roots path while direct-open succeeds; this report concerns a previously selected direct OneDrive workspace that becomes unreadable after restoration in a cold Desktop lifecycle.

Current issue search did not find an exact open OneDrive + EPERM report in openai/codex.

Safety and contact

I do not recommend that users patch app.asar, alter the bundled Codex binary, re-sign the application, reset TCC, or grant Full Disk Access separately to Git/Node/Python. Those actions change the security context under investigation and could create new risks.

I am available to test an OpenAI-signed diagnostic build and provide additional sanitized diagnostics. Please contact me in this issue; if sensitive logs are required, I can use an official private support channel.

View original on GitHub ↗

6 Comments

pioootrek · 1 month ago

I can reproduce the same System Policy denial on a newer Desktop build, but with an important difference: the affected workspace is a normal local directory under ~/Documents, not OneDrive or another File Provider location.

Environment:

  • Codex Desktop: 26.707.72221 (5307)
  • Bundled Codex CLI: 0.144.2
  • macOS: 26.5.2 (25F84), Apple Silicon
  • Workspace: directly selected local directory under ~/Documents
  • Backing volume: /System/Volumes/Data (/dev/disk3s5)
  • The workspace path is not a symlink

Observed behavior:

  • stat() succeeds and reports normal ownership/mode bits.
  • ls, pwd, find, xattr, and Git fail with EPERM / Operation not permitted.
  • Equivalent directory access under /private/tmp succeeds.
  • The kernel attributes the denial to macOS System Policy, not ordinary POSIX permissions.

Sanitized unified-log samples:

(Sandbox) System Policy: ChatGPT(<pid>) deny(1) file-read-data \
/Users/<user>/Documents/<workspace>

(Sandbox) System Policy: git(<pid>) deny(1) file-read-data \
/Users/<user>/Documents/<workspace>

(Sandbox) System Policy: zsh(<pid>) deny(1) file-read-data \
/Users/<user>/Documents/<workspace>

(Sandbox) System Policy: pwd(<pid>) deny(1) file-read-data \
/Users/<user>/Documents/<workspace>

There was also a sustained retry pattern: new Git processes were repeatedly denied at roughly one-second intervals.

This suggests that the failure class may be broader than OneDrive/File Provider restoration. It can also affect a directly selected workspace inside the macOS-protected local Documents directory. The parent ChatGPT process and detached/child processes are both visible in the denial log.

I have not modified TCC state, re-signed the application, or changed repository permissions. I can provide a more tightly bounded sanitized log excerpt or test an OpenAI-signed diagnostic build if useful.

andatt · 1 month ago

Also seeing same issue as described by @pioootrek

jinxiaoliu27-eng · 1 month ago

Recovery sequence and process-lifecycle clue (2026-07-23)

I now have a useful recovery sequence for the original OneDrive case. This is an interim workaround/diagnostic observation, not a claim that the bug is permanently fixed.

Environment at this follow-up

  • macOS: 26.5.2 (25F84), Apple Silicon
  • ChatGPT Desktop / Codex app: 26.715.72359 (5718)
  • bundled Codex CLI: 0.145.0-alpha.30
  • OneDrive reported 26.113.0614 during the immediate recovery check. The currently installed version later became 26.123.0628; the successful access probes had already been observed before that later version change.

Exact sequence

  1. In the failing state, metadata-oriented stat still succeeded, but ls, Git working-directory access, Node.js fs.readdirSync, Python os.listdir, and real file-content reads failed with EPERM / Operation not permitted. The previously restored task rooted in that workspace would not open normally.
  2. I reconnected OneDrive and waited until its app/File Provider processes were active again.
  3. While the existing ChatGPT Desktop process remained running, the same probes still failed. Reconnecting OneDrive alone was not sufficient.
  4. I then fully quit and relaunched ChatGPT Desktop.
  5. Without reinstalling either application, resetting TCC, changing Full Disk Access, patching/re-signing the app, or running a OneDrive reset script, the same directory became usable again:
  • ls succeeded;
  • Node.js and Python directory enumeration succeeded;
  • a real file-content read succeeded;
  • Git reached the directory and returned the expected not a git repository result instead of EPERM;
  • direct navigation to the previously affected restored task succeeded and its history was intact.

A fresh follow-up probe at the time of posting still passes: the workspace can be enumerated by ls, Node.js, and Python, and a real file can be read. OneDrive is actively syncing, so entry counts may change between probes.

Practical workaround for affected users

  1. Confirm that OneDrive has finished syncing important data and back up anything that exists only locally.
  2. Reconnect OneDrive.
  3. Fully quit ChatGPT Desktop (do not merely close its window), then relaunch it.
  4. Reopen/reselect the affected workspace and task.
  5. Verify real directory and content access. Do not treat the OneDrive status icon or a successful stat as proof of recovery.

A useful read-only verification set is:

  • stat as the metadata control;
  • ls / pwd;
  • Node.js fs.readdirSync;
  • Python os.listdir;
  • a small real file-content read;
  • Git working-directory access;
  • restored-task navigation/loading.

For this recovery, reinstalling ChatGPT Desktop or OneDrive was not necessary.

Diagnostic implication

The key distinction is that OneDrive reconnection did not repair access for the already-running Desktop process, but a full Desktop relaunch immediately afterward restored both filesystem access and task navigation. That is consistent with a stale app/process-lifecycle relationship to File Provider authorization or responsible-code attribution. The ordering may matter: provider reconnection first, Desktop relaunch second.

This does not prove a unique root cause, especially because OneDrive later updated during the follow-up window. I will treat the recovery as provisional and update this issue if the failure recurs after another cold relaunch.

dianshili · 1 month ago

Reproduced again on build 5848: account switching is correlated, but not required

The failure has recurred after another Desktop update/relaunch. This follow-up helps separate account switching from the more general cold-start/restored-workspace lifecycle.

Current environment

  • macOS: 26.5.2 (25F84), Apple Silicon
  • ChatGPT Desktop / Codex app: 26.721.41059 (5848)
  • Bundled Codex CLI: 0.146.0-alpha.3.1
  • OneDrive: 26.123.0628

No TCC reset, application reinstall, app re-signing, or permission change was performed.

New recurrence after the Desktop update

The updated Desktop process launched with an already authenticated ChatGPT account. There was no account/logout or account/login/start event in this application session.

Sanitized timeline in UTC:

| Time | Event |
|---|---|
| 04:16:04.583 | Updated Desktop process launches |
| 04:16:13.054 | Existing authenticated ChatGPT account lookup completes |
| 04:16:14.085 | macOS records the first restored-workspace System Policy: git deny(1) file-read-data |
| 04:16:14.275 | Desktop records fatal: Unable to read current working directory: Operation not permitted |
| following seconds | New Git worker PIDs are denied repeatedly, approximately once per second |

Normalized excerpts:

System Policy: git(<pid>) deny(1) file-read-data <redacted-OneDrive-workspace>

Failed to resolve git root and common dir:
fatal: Unable to read current working directory: Operation not permitted

The denial later remained reproducible for additional Git workers and for Codex/shell child processes. The affected paths were restored workspaces inside the OneDrive File Provider tree; local non-File-Provider controls remained usable.

Retrospective account-switch timing check

I also rechecked a previous recurrence on July 24:

| Time (UTC) | Event |
|---|---|
| 00:05:24.022 | Desktop launches under the account that was already authenticated |
| 00:05:54.193 | Existing-account lookup succeeds |
| 00:05:57.922 | First restored-workspace Git Operation not permitted error |
| 00:06:25.878 | User initiates account/logout |
| 00:06:31.289 | User initiates account/login/start |

In that run, the first denial occurred about 28 seconds before logout began. In the current build-5848 run, the denial occurred with no account switch at all.

Updated interpretation

Account switching can still be a practical trigger because signing out/in is often accompanied by account-state restoration, app-server reconstruction, a full quit, or a cold relaunch. However, the newly aligned timelines show that the identity switch itself is neither necessary nor the direct permission cause.

The shared condition across the reproductions is:

  1. a new Desktop process lifecycle begins;
  2. saved OneDrive/File Provider workspaces are restored;
  3. background Git discovery starts immediately;
  4. macOS System Policy denies the worker's directory access;
  5. Desktop continues spawning additional workers against the denied root.

This strengthens the existing hypothesis that restored-workspace validation and child-process/responsible-code attribution are more central than the selected ChatGPT identity.

It also confirms that the previously reported recovery sequence (reconnect OneDrive, then fully relaunch Desktop) was provisional: a later cold relaunch or Desktop update can return the same workspace to the denied state.

Suggested product behavior

  • Before launching restored-root Git discovery, perform a bounded real directory-enumeration probe from both the parent and worker execution contexts.
  • On EPERM/EACCES, suspend further scans for that root rather than spawning a retry storm.
  • Present one explicit reselect/reauthorize action.
  • Include cold restart, update restart, and logout/login restart as separate regression cases; account switching should not be treated as the sole trigger.

I can provide a tightly bounded, privacy-sanitized log excerpt or test an OpenAI-signed diagnostic build if useful.

dianshili · 29 days ago

Severe data-loss incident after recovery escalation (2026-07-29)

This is a serious follow-up to the original report and an important safety clarification to my earlier provisional recovery comment.

Impact

  • The impact to me is severe: approximately 30 GB of files were lost.
  • Those files represented approximately 12 days of work that had not yet been uploaded/synchronized to OneDrive.
  • This became a real production-data incident, not merely temporary workspace unavailability.

Incident sequence

  1. The original failure state recurred: metadata-oriented checks could still succeed, while real directory enumeration, working-directory access, Git, Node.js, Python, and restored-task access failed with EPERM / Operation not permitted.
  2. Codex tasks remained rooted in affected OneDrive/File Provider workspaces. At the same time, OneDrive SyncEngine entered a very high-volume metadata/log retry loop. The available evidence is consistent with Codex access triggering or amplifying the bad File Provider state, although I cannot attribute every individual OneDrive log entry to a specific Codex worker.
  3. During assistant-guided troubleshooting, the recovery procedure escalated to running Microsoft's OneDrive reset workflow and relinking OneDrive.
  4. After the reset/relink sequence, the previous local OneDrive/File Provider state was cleared and rebuilt. Files that had not reached the cloud were no longer present, producing the approximately 30 GB loss described above.

The initial EPERM condition and the later data-loss event should be distinguished technically: the permission/interoperability defect created the failure and retry situation; the severe data loss occurred after the recovery process escalated to OneDrive reset and relink.

Important correction and safety boundary

My earlier provisional workaround in this issue was:

  1. confirm synchronization and independently back up anything that exists only locally;
  2. reconnect OneDrive;
  3. fully quit and relaunch ChatGPT Desktop;
  4. reopen/reselect the workspace; and
  5. verify real enumeration, content reads, Git access, and restored-task loading.

That earlier recovery explicitly did not run a OneDrive reset script. It must not be interpreted as recommending ResetOneDriveApp.command or reset/relink as a safe equivalent.

In retrospect, the existing safety boundary was correct: a OneDrive reset/relink must not be attempted when local-only data has not been independently verified and backed up.

Requested product safeguards

Please treat this as a high-severity data-safety issue and consider:

  • stopping all restored-workspace scans and worker retries for a root immediately after EPERM / EACCES;
  • presenting one explicit reauthorize/reselect workflow instead of continuing background access;
  • validating real parent-and-child directory enumeration before scheduling Git discovery;
  • clearly warning that OneDrive reset/relink can remove local-only data;
  • preventing Codex or an assistant-guided recovery flow from recommending or executing a OneDrive reset unless cloud synchronization and an independent local backup have both been verified;
  • providing a safe way to detach or migrate affected tasks to a normal local workspace without requiring access to the denied root.

I can provide privacy-sanitized timelines and logs through an appropriate private support channel if the maintainers need them.

dianshili · 29 days ago

URGENT: Detailed local data-loss incident after the Codex × OneDrive EPERM failure and recovery escalation (2026-07-29)

Urgent safety warning: If a Codex workspace inside a macOS File Provider root begins returning EPERM / Operation not permitted, do not run a OneDrive reset, unlink/relink the account, remove the File Provider domain, or select “Erase and Set Up OneDrive” until all local-only changes have been independently backed up outside every File Provider-managed directory and their synchronization has been verified from the cloud side. “Cloud files will not be deleted” is not equivalent to “local-only unsynchronized data is safe.”

Maintainers: please treat this as a high-severity data-safety report, not only as another workspace-permission report. The EPERM defect created the operational context; the separate local-data-loss event occurred during an assistant-guided OneDrive recovery escalation. My current best, post-incident estimate is that approximately 30 GB of local-only files or changes are lost/not recovered as of this report, representing approximately 12 days of work that had not yet been uploaded/synchronized to OneDrive.

This is a detailed supplement to my initial incident summary, as well as an important safety clarification to my earlier provisional recovery comment.

I am disclosing the incident in detail so that OpenAI, Microsoft, Apple, other agent/tool developers, and affected users can understand both the technical defect and the dangerous recovery path. Personal directory names, filenames, document contents, account identifiers, and task contents remain redacted.

Executive summary

  • The original stat-may-succeed / real-access-returns-EPERM failure recurred across OneDrive/File Provider workspaces used by Codex Desktop.
  • Multiple Codex tasks and subprocesses continued to use affected OneDrive paths as their working directories.
  • OneDrive SyncEngine then entered a high-volume metadata/diagnostic-log loop, creating approximately 23,000+ .odl / .aodl files and reaching a measured footprint of approximately 22.7 GiB / 24.4 GB decimal.
  • The visible Codex tool-call rate was far lower than the OneDrive log-generation rate. The evidence supports Codex access as a plausible trigger or amplifier, but it does not prove that every OneDrive log file corresponded to a separate Codex request.
  • During troubleshooting, an assistant-guided procedure escalated to Microsoft's bundled ResetOneDriveApp.command, followed by attempts to relink/reuse the existing local OneDrive folder.
  • The first reset left a dated local OneDrive archive intact with a measured footprint of 103,471,452 KiB (approximately 98.7 GiB / 106.0 GB decimal). This was the size of the local domain/archive, not the amount ultimately lost. The later relink/domain recreation moved much of that old local content into macOS File Provider Purgatory.
  • fileproviderd continued reclaiming that cache even after the OneDrive app had been stopped: the observed Purgatory footprint fell from 88,279,484 KiB (approximately 84.2 GiB / 90.4 GB) to 15,636,464 KiB (approximately 14.9 GiB / 16.0 GB). Over the corresponding observations, reported free space rose by 82,850,868 KiB (approximately 79.0 GiB / 84.8 GB), and previously available project paths disappeared. This released-space figure includes cache/re-downloadable content and must not be read as the amount of permanently lost local-only work.
  • No direct shell deletion command targeted the user's OneDrive content tree, and the Trash was not emptied. The bulk diagnostic .odl / .aodl logs were intentionally removed separately to recover disk space. No cloud-side deletion was confirmed. The destructive result affecting the content tree came from the reset/relink/File Provider cleanup chain. Files that had already reached the cloud were not shown to be deleted; the critical loss concerned local-only, not-yet-synchronized work.
  • My current, user-estimated impact is approximately 30 GB of local-only files or changes lost/not recovered as of this report, including approximately 12 days of work that had not yet synchronized.

Environment

  • macOS: 26.5.2 (25F84)
  • Architecture: Apple Silicon / arm64
  • Exact ChatGPT Desktop / Codex app build active during the reset/relink window: not independently captured
  • Same EPERM defect reproduced earlier that day on Desktop build: 26.721.41059 (5848)
  • Current post-reinstallation build at report time, not claimed as the incident build: 26.721.81911 (5973)
  • Bundled Codex CLI recorded in the incident sessions: 0.146.0-alpha.3.1
  • OneDrive: 26.123.0628 (internal build 26123.0628.0001)
  • Workspace class: directly selected workspaces inside the macOS OneDrive File Provider tree under ~/Library/CloudStorage/OneDrive-…
  • Control paths: /private/tmp and ordinary non-File-Provider local paths remained usable

Before the incident, Full Disk Access and the relevant File Provider/TCC grants had been observed as allowed. OneDrive and File Provider processes could be running while Codex still could not enumerate the affected directories. This was not explained by normal POSIX mode bits, a missing path, a Git configuration error, or a general inability to launch shell tools.

Relevant build history already documented in this issue:

| Stage | Desktop / Codex app | Bundled CLI | OneDrive |
|---|---|---|---|
| Original issue reproduction | 26.707.62119 (5211) | 0.144.2 | File Provider case |
| Provisional reconnect + full Desktop relaunch recovery | 26.715.72359 (5718) | 0.145.0-alpha.30 | initially 26.113.0614, later 26.123.0628 |
| Same-day recurrence with no account switch | 26.721.41059 (5848) | 0.146.0-alpha.3.1 | 26.123.0628 |
| Current post-reinstallation/report-time build | 26.721.81911 (5973) | not used here to identify the incident build | 26.123.0628 |

The exact Desktop build active during the reset/relink window was not independently captured, so this report does not attribute that recovery incident to build 5973. The wider EPERM defect spans multiple documented builds.

Prior history of this exact bug

This issue was originally filed after repeated reproduction of the following half-failed state:

Operation not permitted
EPERM: operation not permitted, scandir
PermissionError: [Errno 1] Operation not permitted
fatal: Unable to read current working directory: Operation not permitted
System Policy: <process>(<pid>) deny(1) file-read-data <redacted-workspace>

The characteristic boundary is:

  • path/metadata checks such as stat may succeed;
  • real directory enumeration (ls, find, Node.js fs.readdirSync, Python os.listdir) fails;
  • pwd / working-directory resolution fails;
  • Git fails before normal repository handling;
  • known file-content reads may fail;
  • restored Codex tasks remain present in local history but cannot resume because their workspace cannot be read.

On 2026-07-23 I posted a provisional recovery observation: reconnect OneDrive, then fully quit and relaunch ChatGPT Desktop, reselect/reopen the workspace, and verify real access. That recovery explicitly occurred without running a OneDrive reset script.

On 2026-07-25 I reported that the failure recurred again on a later Desktop build even when no account switch occurred. That already showed that the workaround was provisional and that the shared condition was the cold-start/restored-workspace lifecycle, followed by background Git discovery against a denied root.

Detailed incident timeline

Times below are China Standard Time (UTC+8) with UTC equivalents where important.

| Time | Observed event |
|---|---|
| 13:00–13:30 (05:00–05:30 UTC) | Across the recorded Codex sessions, approximately 70 deduplicated Codex subprocess records used OneDrive paths as cwd. These are not claimed to be 70 unique user requests. At least six records contained explicit OneDrive/workspace access failures, including Python PermissionError, document-read Operation not permitted, and current working directory must be readable. Most other visible subprocess launches still succeeded, consistent with a state-dependent/partial failure. |
| 13:30:54 (05:30:54 UTC) | Earliest retained abnormal OneDrive SyncEngine .odl timestamp. The first files appeared roughly every 0.07–0.14 seconds. |
| 13:32–14:00 | Retained minute buckets reached as high as approximately 1,008 diagnostic files per minute. One measured 10-second interval produced 59 new files. |
| 13:57 (05:57 UTC) | Approximately 16,288 diagnostic files occupied 17,079,252,415 bytes (approximately 15.9 GiB / 17.1 GB). |
| 14:01 (06:01 UTC) | Count reached approximately 18,360; disk free space was falling rapidly. |
| approximately 14:11 | Count reached approximately 22,655 files with a measured directory footprint of 23,293,836 KiB (approximately 22.2 GiB / 23.9 GB). |
| approximately 14:13 | OneDrive was stopped. The count stabilized at approximately 23,186 files and 23,840,612 KiB (approximately 22.7 GiB / 24.4 GB). |
| approximately 14:19 | The sampled diagnostic logs were deleted to recover disk space after the loop had been stopped. The log directory fell to a few megabytes and free disk space recovered to roughly 57.9 GB. |
| approximately 14:27 | A restart test caused the log storm to recur. OneDrive was stopped again. Across cleanup and the restart test, approximately 23,426 .odl / .aodl files were ultimately removed. |
| 14:28:46 | I approved the first reset only after the assistant recommended it. The assurance focused on cloud files and did not explain the risk to local-only unsynchronized data. |
| 14:29:21 (06:29:21 UTC) | First execution of /Applications/OneDrive.app/Contents/Resources/ResetOneDriveApp.command. The assistant's pre-approval explanation described clearing local OneDrive application state/login cache and rebuilding the sync connection, but it did not adequately communicate the risk to local-only unsynchronized data. |
| 14:32:43 | The reset's /removedomains process began removing the original File Provider domain. Reported free space rose during the removal/archive transition. |
| 14:35:27 | The reset completed with Removed OneDrive (Personal). A dated archive containing 17 top-level project folders and a measured footprint of 103,471,452 KiB (approximately 98.7 GiB / 106.0 GB) remained visible. This local-domain footprint included synchronized/cache content and was not the amount ultimately lost. |
| approximately 14:42 | The assistant described the state as safe because the dated archive and a known project were still visible and the log storm had not immediately returned. |
| approximately 14:51 | The assistant instructed me to choose the UI action equivalent to “Erase and Set Up OneDrive,” describing the erase as removal of the failed local connection/cache rather than cloud data. |
| 15:03–15:06 | After macOS folder-access authorization, the assistant guided the setup UI to the standard OneDrive entry path. |
| 15:06:50–15:07:03 | The location was selected and the setup UI advanced. |
| 15:07:32 | A new active File Provider domain had been created instead of an in-place reattachment. |
| approximately 15:08 | I observed that OneDrive was rebuilding/redownloading. OneDrive was stopped. |
| 15:10:35 (07:10:35 UTC) | After the unexpected new-domain behavior, I explicitly asked for restoration/reconnection. The assistant selected and executed a second OneDrive reset as the recovery method, attempting to remove the newly created domain and restore the original path. |
| 15:11:05 | Removal of the second File Provider domain was recorded. |
| 15:11:43–15:11:47 | The dated local archive was moved back to the original path while OneDrive remained stopped. Its measured footprint was 103,471,452 KiB (approximately 98.7 GiB / 106.0 GB), and known project paths were readable again. |
| approximately 15:14 | The assistant cited the official “use this folder” flow and asserted that unchanged files would not be redownloaded. |
| approximately 15:16–15:17 | The “Use This Folder” prompt was accepted through UI automation. macOS/OneDrive created another active File Provider domain rather than leaving the old tree in place. |
| 15:17:47 | The original known project path already returned ENOENT. OneDrive was stopped while the underlying File Provider state was investigated. |
| 15:19:22–15:19:49 | Much of the former local content was located under macOS File Provider Purgatory; its measured footprint was 88,279,484 KiB (approximately 84.2 GiB / 90.4 GB), and a known project was initially still locatable there. |
| 15:21:34 | The known project path had disappeared from Purgatory. |
| 15:22:20 | Even though the OneDrive app was stopped, fileproviderd continued cleanup. Purgatory had fallen to 15,636,464 KiB (approximately 14.9 GiB / 16.0 GB), while reported free space had risen to 166,929,924 KiB. Across the relevant free-space observations, the increase was 82,850,868 KiB (approximately 79.0 GiB / 84.8 GB). All further OneDrive/File Provider mutation was stopped. |
| Afterward | My post-incident assessment produced the current user estimate: approximately 30 GB of local-only files or changes lost/not recovered, representing approximately 12 days of unsynchronized work. |

Measurement notes:

  • raw du / df values in this report are 1-KiB blocks and are labeled KiB;
  • GiB conversions are binary, while GB conversions are decimal;
  • counts, directory footprints, and free-space values are point-in-time observations and should not be forced into a byte-for-byte conservation equation;
  • exact timestamps come from retained command/session records; entries marked “approximately” were reconstructed from the surrounding recorded sequence;
  • the approximately 30 GB / 12 days impact figure is my post-incident estimate of local-only work currently lost or not recovered, not a claim that the entire approximately 106.0 GB local-domain footprint was unique or permanently lost.

OneDrive log-storm evidence

The diagnostic-log directory was under the standard OneDrive container log area. At the peak:

  • more than 23,000 .odl / .aodl files had been produced;
  • measured checkpoints included 23,293,836 KiB (approximately 22.2 GiB / 23.9 GB) and 23,840,612 KiB (approximately 22.7 GiB / 24.4 GB);
  • individual files were commonly around 1 MB;
  • sustained rates reached hundreds of files per minute, with an observed peak near 1,008 files/minute;
  • one measured interval produced 59 new diagnostic files in 10 seconds;
  • disk free space fell from roughly 54.7 GB into the approximately 40 GB range before intervention.

Decoded strings from a sampled log repeatedly contained OneDrive internal paths/events such as:

MacboxSyncRootManager
GetUserSelectedPath
getDataXattr
AssignIdsToDriveChange
libraryError

One sampled frequency pass contained approximately:

  • MacboxSyncRootManager: 543 occurrences
  • GetUserSelectedPath: 360 occurrences
  • getDataXattr: 359 occurrences
  • AssignIdsToDriveChange: 138 occurrences
  • libraryError: 69 occurrences

The decoded sample did not contain a literal Codex string or a recognizable user project path. The full raw .odl / .aodl corpus was later removed to recover disk space, so I cannot provide the entire 23+ GB corpus. However, counts, timestamps, sampled strings, disk measurements, Codex session records, and relevant application/unified-log excerpts were preserved in the investigation record and can be sanitized for private review.

Evidence-retention boundary:

| Evidence | Current status |
|---|---|
| Full approximately 23+ GB .odl / .aodl corpus | No longer available; intentionally removed after OneDrive was stopped to relieve acute disk pressure |
| Aggregate file counts, rates, timestamps, and size checkpoints | Preserved in the investigation chronology |
| Decoded sample strings and sampled occurrence counts | Preserved |
| Codex session/tool chronology and reset/relink command records | Preserved |
| Relevant sanitized application and macOS unified-log excerpts | Retained or reconstructable for private review |
| Complete cloud-vs-local forensic manifest | Not available; this is why the approximately 30 GB / 12 days impact remains explicitly labeled a user estimate |
| Private paths, project names, task IDs, account/domain IDs, and document contents | Intentionally excluded from the public issue |

Causality boundary: what is established and what is not

Established:

  1. The Codex × macOS System Policy × OneDrive/File Provider EPERM failure existed before the log storm.
  2. Multiple Codex tasks and subprocesses continued to use OneDrive workspaces as cwd, and explicit access failures occurred.
  3. OneDrive SyncEngine entered a massive internal metadata/log loop shortly afterward.
  4. The log loop stopped when OneDrive was stopped and recurred during a restart test.
  5. The severe local-data loss occurred only after the later reset/relink/File Provider cleanup sequence.

Strongly supported, but not uniquely attributable to one vendor or component:

  1. Codex access against restored workspaces in the denied File Provider state may have triggered, awakened, or amplified the abnormal provider state.
  2. The reset/relink/domain-recreation chain was the proximate operational path by which the old local tree entered Purgatory and local bytes were then reclaimed.
  3. The overall failure crossed application, agent, OneDrive SyncEngine, macOS File Provider, and System Policy boundaries; the current evidence does not identify a single exclusive root cause.

Not established:

  1. It is not proven that Codex directly generated one filesystem request for every .odl file.
  2. Visible Codex operations were only on the order of approximately 2.3 subprocess operations per minute in the 30-minute pre-storm window, not hundreds or thousands per minute.
  3. The hundreds-to-thousands-per-minute rate was the OneDrive SyncEngine's own diagnostic/retry output once the loop began.
  4. There was no process-to-event trace capable of assigning every OneDrive internal retry to a specific Codex PID.
  5. No explicit user-visible Codex tool call was recorded in the roughly two-minute interval around the earliest retained abnormal ODL timestamp. Background/restored-workspace activity may still have been present, but exact trigger attribution is unavailable.
  6. No evidence establishes that OpenAI, Microsoft, or Apple alone caused the entire incident.
  7. No cloud-side mass deletion was observed.
  8. The approximately 106.0 GB local-domain footprint is not the amount lost.
  9. The approximately 30 GB estimate is not claimed to be a file-by-file forensic finding or proof that every byte is permanently unrecoverable.
  10. Network/VPN routing was not established as the root cause.

The responsible wording is therefore:

Codex repeatedly used workspaces in an abnormal/denied OneDrive File Provider state and may have triggered, awakened, or amplified that state; OneDrive SyncEngine then entered its own high-frequency metadata/log loop. The existing evidence does not support claiming that every SyncEngine retry was a separate Codex command.

Network routing was investigated but was not shown to be causal.

How the local data was cleared

This was not a direct rm accident:

  • no recursive delete command targeted the OneDrive data tree;
  • the Trash was not emptied;
  • no cloud-side deletion was confirmed;
  • the first reset initially left the dated archive visible at a measured 103,471,452 KiB (approximately 98.7 GiB / 106.0 GB), which was the local-domain footprint rather than the amount lost.

The destructive transition occurred when reset/relink recreated the File Provider domain and the old local data was moved into the File Provider cache/Purgatory. The operating system then reclaimed that cache. The Purgatory fall from 88,279,484 KiB to 15,636,464 KiB, together with the independently observed 82,850,868 KiB free-space increase, shows that local bytes were actually being released, not merely hidden from Finder. That released space included synchronized cache/re-downloadable content; it is not a measurement of permanent loss and must not be conflated with my separate approximately 30 GB local-only-loss estimate.

Already synchronized cloud files were not shown to be deleted. The loss exposure was the local-only delta: new or modified files that had not yet reached OneDrive. My present user estimate is approximately 30 GB of local-only files or changes currently lost/not recovered and approximately 12 days of work.

Assistant/tooling safety failure

This incident also exposes a critical safety failure for agentic developer tools:

  1. The user requested diagnosis and recovery of a known File Provider interoperability defect.
  2. The assistant inspected Microsoft's bundled reset script and recommended the official reset workflow after the log storm recurred.
  3. I approved the first reset only after the assistant recommended it and represented that it would not delete cloud data. The approval followed an incomplete risk disclosure that omitted the danger to local-only unsynchronized data. The missing preconditions—independent cloud-side synchronization verification and a readable backup outside File Provider—were not performed.
  4. No independent backup of the measured 103,471,452 KiB local domain/archive was completed before reset/relink. That footprint included synchronized/cache content and is not claimed as the amount lost.
  5. The assistant incorrectly assumed that “use this folder” would safely reuse the old local data in place.
  6. After the first domain recreation behaved unexpectedly, I explicitly asked to restore/reconnect the prior state; however, the assistant selected and executed the second reset/relink method and supplied the inaccurate safety assurance.
  7. Only after Purgatory began shrinking and project paths disappeared was the workflow frozen.

The earlier comment in this issue had already stated the correct safety boundary: back up local-only data first, and do not treat a successful stat, provider status icon, or reconnection alone as proof of recovery. The later assistant-guided workflow failed to respect that boundary.

This should not be dismissed as “the user ran Microsoft's reset tool.” An AI coding agent participated in diagnosis, recommended the escalation, executed the reset commands with system approval, guided the relink UI, and provided incomplete assurances. Agent systems need explicit protections against this class of cloud-storage destructive escalation.

Impact

  • User-estimated approximately 30 GB of local-only files or changes lost/not recovered as of this report.
  • User-estimated approximately 12 days of professional work had not yet synchronized.
  • Multiple active projects became unavailable from their original workspace paths.
  • Codex task histories were still present locally, but tasks tied to the inaccessible/missing workspace paths could not reliably resume.
  • Approximately 24 GB of runaway diagnostic logs created acute disk-pressure risk before cleanup.
  • Substantial downtime and additional recovery/audit effort followed.

The affected files included professional work products. Their private names and contents are intentionally not included in this public report.

Requested action from OpenAI

Please assign an owner and treat this as an urgent data-safety defect. At minimum:

  1. Circuit-break denied workspaces. On the first restored-root EPERM / EACCES, stop Git discovery, shell startup, indexing, and all retrying workers for that root. Apply root-level exponential backoff plus hard retry and diagnostic-log limits.
  2. Validate real access before restoration. Test bounded parent-and-child open/readdir behavior, not only path existence or stat, before starting background work.
  3. Provide a safe recovery state. Show one explicit “reauthorize/reselect/detach workspace” action and keep the task history readable even when its old cwd is unavailable.
  4. Provide task rebind and guarded data migration. Allow task/session metadata and its cwd to be rebound to an ordinary local workspace without accessing the denied root. Offer file migration only after the source becomes readable and an independent backup has been verified.
  5. Add a restored-workspace safe mode. Let users start Codex without automatically scanning any saved File Provider roots.
  6. Protect destructive cloud operations. Codex and assistant workflows should never recommend or execute OneDrive reset, unlink, domain removal, relink, or cache cleanup unless all of the following are verified:
  • cloud synchronization is complete;
  • local-only files are inventoried;
  • an independent backup exists and is readable;
  • the user receives a specific warning that local-only data can be lost;
  • explicit confirmation is obtained for the exact destructive scope.
  1. Add regression coverage. Test local, OneDrive, iCloud, ~/Documents, cold restart, app update, logout/login, stopped-provider, and restored-task scenarios using OpenAI-signed builds.
  2. Add privacy-preserving diagnostics. Record random run ID, executable identity, PID/PPID/process-group/session relationships, provider class, access-test stage, errno, retry count, and circuit-break state—without recording user paths, filenames, account identifiers, remotes, or document content.
  3. Bound disk impact. A denied root must never produce unbounded worker creation or multi-gigabyte diagnostic/log amplification.
  4. Publish a safety advisory. Warn users not to run OneDrive reset/relink as a generic Codex workspace repair and explain how to preserve local-only files before any provider lifecycle change.
  5. Require human takeover for destructive provider UI. “Erase and Set Up,” reset, unlink, relink, domain removal, cache cleanup, and “Use This Folder” during a recovery incident must not be auto-clicked by an assistant.
  6. Mark and triage the issue accordingly. Please add an appropriate data-loss/high-severity label, name an engineering owner, and publish a visible interim safety status.

Requested action from Microsoft and Apple

Microsoft OneDrive/File Provider engineers:

  • document prominently that reset/relink can endanger local-only files even when cloud files remain safe;
  • provide a pre-reset inventory of unsynchronized/local-only data;
  • retain displaced local content in a recoverable quarantine until the user explicitly confirms the new domain is complete;
  • prevent background Purgatory reclamation while relink/recovery is unresolved;
  • expose a supported recovery/export path for local-only File Provider content.

Apple File Provider/System Policy engineers:

  • investigate why an authorized parent application and its new-session/detached child processes can receive inconsistent System Policy deny(1) file-read-data outcomes;
  • provide a supported way for applications to revalidate responsible-code/File Provider access after relaunch;
  • make cache/Purgatory transitions observable and recoverable before local bytes are reclaimed;
  • ensure that provider-domain recreation cannot silently turn an attempted reattachment into local-only data eviction.

Request to other agent and developer-tool authors

Please treat cloud-provider reset/unlink/relink commands as potentially destructive, even if vendor documentation says cloud files will not be deleted. “Cloud files are safe” is not equivalent to “local-only work is safe.”

Agentic tools should:

  • stop on EPERM instead of repeatedly probing;
  • move diagnostic work to a normal local directory;
  • require a verified, independent backup before any File Provider lifecycle mutation;
  • never infer that “use existing folder” means an in-place, lossless reattachment;
  • keep a human-readable action log and provide an immediate hard stop;
  • preserve the user's ability to access task history when a workspace path fails.

Request to affected users

If you encounter the same signature:

  1. stop Codex/IDE activity against the denied workspace;
  2. do not run OneDrive reset/unlink/relink merely to repair Codex access;
  3. if the source is still readable, preserve all local-only files to an independent non-File-Provider location first; if it is not readable, stop and seek recovery assistance rather than escalating provider lifecycle operations;
  4. record app versions, exact timestamps, and sanitized System Policy errors;
  5. verify recovery with ls, pwd, Node/Python enumeration, a real content read, Git access, and task loading—not stat or a green sync icon alone;
  6. add a sanitized report here so maintainers can measure the scope.

Final request

OpenAI: please acknowledge this report, assign an engineering owner, coordinate with Microsoft and Apple, and provide either a fixed build or a signed diagnostic A/B build as soon as possible. The issue is now associated with a concrete, substantial data-loss incident. The current behavior is not merely inconvenient: the combination of restored-workspace access failure, repeated background work, and unsafe recovery escalation can destroy local-only professional work.

I am willing to provide sanitized Codex logs, session timelines, command records, and retained diagnostic excerpts through an official private support channel.