curated-plugin sync runs `git reset --hard` against the user's project repo
What version of Codex CLI is running?
0.139.0
What subscription do you have?
Plus
Which model were you using?
Last run: gpt-5.5 (no codex instances running at the time of the bug)
What platform is your computer?
Darwin 25.5.0 arm64 arm
What terminal emulator and version are you using (if applicable)?
Ghostty (again, not running at time of bug)
Codex doctor report
{
"schemaVersion": 1,
"generatedAt": "1782346342s since unix epoch",
"overallStatus": "ok",
"codexVersion": "0.139.0",
"checks": {
"app_server.status": {
"id": "app_server.status",
"category": "app-server",
"status": "ok",
"summary": "background server is not running",
"details": {
"control socket": "/Users/mordecai/.codex/app-server-control/app-server-control.sock",
"daemon state dir": "/Users/mordecai/.codex/app-server-daemon",
"mode": "ephemeral",
"pid file": "/Users/mordecai/.codex/app-server-daemon/app-server.pid (missing)",
"settings": "/Users/mordecai/.codex/app-server-daemon/settings.json (missing)",
"status": "not running",
"update-loop pid file": "/Users/mordecai/.codex/app-server-daemon/app-server-updater.pid (missing)"
},
"remediation": null,
"durationMs": 0
},
"auth.credentials": {
"id": "auth.credentials",
"category": "auth",
"status": "ok",
"summary": "auth is configured",
"details": {
"auth file": "/Users/mordecai/.codex/auth.json",
"auth storage mode": "File",
"stored API key": "false",
"stored ChatGPT tokens": "true",
"stored agent identity": "false",
"stored auth mode": "chatgpt"
},
"remediation": null,
"durationMs": 0
},
"config.load": {
"id": "config.load",
"category": "config",
"status": "ok",
"summary": "config loaded",
"details": {
"CODEX_HOME": "/Users/mordecai/.codex",
"config.toml": "/Users/mordecai/.codex/config.toml",
"config.toml parse": "ok",
"cwd": "/Users/mordecai",
"enabled feature flags": "shell_tool, unified_exec, shell_snapshot, terminal_resize_reflow, sqlite, hooks, enable_request_compression, multi_agent, apps, tool_suggest, plugins, in_app_browser, browser_use, browser_use_external, computer_use, plugin_sharing, image_generation, skill_mcp_dependency_install, steer, guardian_approval, goals, collaboration_modes, tool_call_mcp_elicitation, personality, fast_mode, tui_app_server, prevent_idle_sleep, workspace_dependencies",
"feature flag overrides": "prevent_idle_sleep=true",
"feature flags enabled": "28",
"log dir": "/Users/mordecai/.codex/log",
"mcp servers": "0",
"model": "gpt-5.5",
"model provider": "openai",
"sqlite home": "/Users/mordecai/.codex"
},
"remediation": null,
"durationMs": 0
},
"git.environment": {
"id": "git.environment",
"category": "git",
"status": "ok",
"summary": "git version 2.50.1 (Apple Git-155)",
"details": {
"PATH git #1": "/usr/bin/git",
"PATH git entries": "1",
"git build options": "git version 2.50.1 (Apple Git-155); cpu: arm64; no commit associated with this build; sizeof-long: 8; sizeof-size_t: 8; shell-path: /bin/sh; feature: fsmonitor--daemon; libcurl: 8.7.1; zlib: 1.2.12; SHA-1: SHA1_DC; SHA-256: SHA256_BLK",
"git exec path": "/Applications/Xcode.app/Contents/Developer/usr/libexec/git-core",
"git version": "git version 2.50.1 (Apple Git-155)",
"repo detected": "false",
"selected git": "/usr/bin/git"
},
"remediation": null,
"durationMs": 17
},
"installation": {
"id": "installation",
"category": "install",
"status": "ok",
"summary": "installation looks consistent",
"details": {
"PATH codex #1": "/opt/homebrew/bin/codex",
"current executable": "/opt/homebrew/bin/codex",
"install context": "brew",
"managed by bun": "false",
"managed by npm": "false",
"managed package root": "not set"
},
"remediation": null,
"durationMs": 2
},
"mcp.config": {
"id": "mcp.config",
"category": "mcp",
"status": "ok",
"summary": "no MCP servers configured",
"details": {},
"remediation": null,
"durationMs": 0
},
"network.env": {
"id": "network.env",
"category": "network",
"status": "ok",
"summary": "network-related environment looks readable",
"details": {
"proxy env vars": "none"
},
"remediation": null,
"durationMs": 0
},
"network.provider_reachability": {
"id": "network.provider_reachability",
"category": "reachability",
"status": "ok",
"summary": "active provider endpoints are reachable over HTTP",
"details": {
"ChatGPT base URL": "https://chatgpt.com/backend-api/ reachable (HTTP 403)",
"reachability mode": "ChatGPT auth"
},
"remediation": null,
"durationMs": 159
},
"network.websocket_reachability": {
"id": "network.websocket_reachability",
"category": "websocket",
"status": "ok",
"summary": "Responses WebSocket handshake succeeded",
"details": {
"DNS": "2 IPv4, 0 IPv6, first IPv4",
"auth mode": "chatgpt",
"connect timeout": "15000 ms",
"endpoint": "wss://chatgpt.com/backend-api/<redacted>",
"handshake result": "HTTP 101 Switching Protocols",
"model provider": "openai",
"models etag present": "true",
"provider name": "OpenAI",
"proxy env vars": "none",
"reasoning header": "false",
"server model present": "false",
"supports websockets": "true",
"wire API": "responses"
},
"remediation": null,
"durationMs": 650
},
"runtime.provenance": {
"id": "runtime.provenance",
"category": "runtime",
"status": "ok",
"summary": "running brew on macos-aarch64",
"details": {
"commit": "unknown",
"current executable": "/opt/homebrew/bin/codex",
"install method": "brew",
"platform": "macos-aarch64",
"version": "0.139.0"
},
"remediation": null,
"durationMs": 0
},
"runtime.search": {
"id": "runtime.search",
"category": "search",
"status": "ok",
"summary": "search is OK (system)",
"details": {
"search command": "rg",
"search command readiness": "ripgrep 14.1.1",
"search provider": "system"
},
"remediation": null,
"durationMs": 2
},
"sandbox.helpers": {
"id": "sandbox.helpers",
"category": "sandbox",
"status": "ok",
"summary": "sandbox configuration is readable",
"details": {
"approval policy": "OnRequest",
"codex-linux-sandbox helper": "none",
"execve wrapper helper": "/Users/mordecai/.codex/tmp/arg0/codex-arg0MKpseO/codex-execve-wrapper",
"filesystem sandbox": "restricted",
"network sandbox": "restricted"
},
"remediation": null,
"durationMs": 0
},
"state.paths": {
"id": "state.paths",
"category": "state",
"status": "ok",
"summary": "state paths and databases are inspectable",
"details": {
"CODEX_HOME": "/Users/mordecai/.codex (dir)",
"active rollout files": "115 files, 72657657 total bytes, 631805 average bytes",
"archived rollout files": "0 files, 0 total bytes, 0 average bytes",
"goals DB": "/Users/mordecai/.codex/goals_1.sqlite (file)",
"goals DB integrity": "ok",
"log DB": "/Users/mordecai/.codex/logs_2.sqlite (file)",
"log DB integrity": "ok",
"log dir": "/Users/mordecai/.codex/log (dir)",
"memories DB": "/Users/mordecai/.codex/memories_1.sqlite (file)",
"memories DB integrity": "ok",
"sqlite home": "/Users/mordecai/.codex (dir)",
"state DB": "/Users/mordecai/.codex/state_5.sqlite (file)",
"state DB integrity": "ok"
},
"remediation": null,
"durationMs": 117
},
"state.rollout_db_parity": {
"id": "state.rollout_db_parity",
"category": "threads",
"status": "ok",
"summary": "rollout files and state DB thread inventory agree",
"details": {
"default model provider": "openai",
"rollout DB active files": "115",
"rollout DB active rows": "115",
"rollout DB archive mismatches": "0",
"rollout DB archived files": "0",
"rollout DB archived rows": "0",
"rollout DB duplicate DB paths": "0",
"rollout DB duplicate rollout thread ids": "0",
"rollout DB malformed file names": "0",
"rollout DB missing active rows": "0",
"rollout DB missing archived rows": "0",
"rollout DB model providers": "openai=115",
"rollout DB rows": "115",
"rollout DB scan cap reached": "false",
"rollout DB scan errors": "0",
"rollout DB sources": "cli=97, subagent:other=14, subagent:thread_spawn=3, vscode=1",
"rollout DB stale rows": "0"
},
"remediation": null,
"durationMs": 327
},
"system.environment": {
"id": "system.environment",
"category": "system",
"status": "ok",
"summary": "OS language en-US",
"details": {
"EDITOR": "set",
"LANG": "en_US.UTF-8",
"VISUAL": "not set",
"os": "Mac OS 26.5.1 [64-bit]",
"os language": "en-US",
"os type": "Mac OS",
"os version": "26.5.1"
},
"remediation": null,
"durationMs": 2
},
"terminal.env": {
"id": "terminal.env",
"category": "terminal",
"status": "ok",
"summary": "terminal metadata was detected",
"details": {
"COLORTERM": "truecolor",
"TERMINFO": "/Applications/Ghostty.app/Contents/Resources/terminfo (dir)",
"TERM_PROGRAM": "ghostty",
"color output": "disabled (stdout is not a terminal)",
"effective locale": "en_US.UTF-8",
"stderr is terminal": "true",
"stdin is terminal": "true",
"stdout is terminal": "false",
"terminal": "Ghostty",
"terminal size": "167x51",
"terminal version": "1.3.1"
},
"remediation": null,
"durationMs": 0
},
"terminal.title": {
"id": "terminal.title",
"category": "title",
"status": "ok",
"summary": "terminal title default",
"details": {
"terminal title activity": "true",
"terminal title items": "activity, project-name",
"terminal title project source": "cwd",
"terminal title project value": "mordecai",
"terminal title source": "default"
},
"remediation": null,
"durationMs": 0
},
"updates.status": {
"id": "updates.status",
"category": "updates",
"status": "ok",
"summary": "update configuration is locally consistent",
"details": {
"cached latest version": "0.142.0",
"check for update on startup": "true",
"dismissed version": "0.138.0",
"last checked at": "2026-06-24T23:32:44.544156Z",
"latest version": "0.142.0",
"latest version status": "newer version is available",
"update action": "brew upgrade --cask codex",
"version cache": "/Users/mordecai/.codex/version.json"
},
"remediation": null,
"durationMs": 83
}
}
}
What issue are you seeing?
Codex's curated-plugin sync (plugins."github@openai-curated") shells out to git without pinning the target repository. When the Codex process's current working directory is an unrelated user git repo, the sync fetches into, writes a refs/codex/curated-sync ref to, andgit reset --hards that repo's checked-out branch onto the marketplace commit, and silently replaces the current workspace with the contents of github.com/openai/plugins and discards any uncommitted work. Codex was not open (although it was last used in this directory). git reflog shows:
7fd3161 (grafted, HEAD -> main) HEAD@{0}: reset: moving to refs/codex/curated-sync
b8e9235 ({branch-name}) HEAD@{1}: checkout: moving from {branch-name} to main.
Both repos ended up with a refs/codex/curated-sync ref. This is a data-loss bug; my work was only spared because my changes happened to be committed on other branches / stashed.
What steps can reproduce the bug?
- Enable the curated plugin source:
[plugins."github@openai-curated"] enabled = true. - Start Codex with its working directory set to an arbitrary git repository that isn't the plugin staging clone (e.g. open Codex in any project).
- (??) Trigger / wait for a curated-plugin sync. (This was very non deterministic; absolutely no clue if this is reproducible)
- Observe the project repo: a
refs/codex/curated-syncref appears and the checked-out branch is hard-reset onto the marketplace commit; the working tree is replaced.
What is the expected behavior?
Literally anything else; not running git reset --hard on a user repository?
Additional information
Can provide more details/logs upon request.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗