Run the verifier test suite and inspect the generated metadata:
node --test scripts/lib/upstream-linux-package.test.js
./install.sh --inspect --report-dir /tmp/codex-inspectDo not bypass a signature or hash failure. Confirm system time, HTTPS access to
persistent.oaistatic.com, gpgv, the pinned key fingerprint, and sufficient
disk space. An explicit package must match host architecture and be named
chatgpt in control metadata.
/opt/codex-desktop/start.sh --diagnose
/opt/codex-desktop/ChatGPT --version
journalctl --user -u codex-update-manager.service --no-pagerThe diagnostic checks the official executable, ASAR, bundled codex, rg, and
code-mode host. It also warns when Chromium sandbox prerequisites are missing.
Also confirm that the installed package architecture matches the machine and that no official ChatGPT process is already holding the shared profile lock:
uname -m
pgrep -a -f '(/ChatGPT|/chatgpt)' || trueDo not start the underlying ChatGPT binary directly for normal use. The
codex-desktop wrapper supplies the correct desktop identity and enabled
feature hooks.
The launcher reads shared Electron flags from
${XDG_CONFIG_HOME:-$HOME/.config}/electron-flags.conf and Community-specific
flags from
${XDG_CONFIG_HOME:-$HOME/.config}/codex-desktop/electron-flags.conf, in that
order. Put one complete argument on each line; blank lines and lines beginning
with # are ignored. App-specific flags are followed by enabled feature flags
and explicit command-line arguments, so a later explicit argument can override
an earlier setting.
To force native Wayland rendering without editing a generated desktop entry:
mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/codex-desktop"
printf '%s\n' '--ozone-platform=wayland' > \
"${XDG_CONFIG_HOME:-$HOME/.config}/codex-desktop/electron-flags.conf"Restart every running official and Community process after changing the file. The launcher does not evaluate shell quoting or split a line into multiple arguments.
Prefer a native package, which installs an AppArmor profile adapted to
/opt/codex-desktop/ChatGPT. AppImage intentionally refuses to disable the
sandbox automatically. Enable unprivileged user namespaces according to your
distribution policy or use the native package.
If a native package was copied between systems, verify its adapted profile and reload AppArmor according to the distribution's tooling. Never solve a packaging error by globally disabling Chromium sandboxing.
The official package should appear as ChatGPT. This project should appear
as ChatGPT Community with a blue C mark. Confirm the selected entry:
grep -H '^Name=' \
/usr/share/applications/chatgpt.desktop \
/usr/share/applications/codex-desktop.desktop 2>/dev/null || trueAfter upgrading from an older package, refresh the desktop database or log out and in if your shell keeps stale names or icons. Do not rename the official desktop file to work around a shell cache.
Both use the upstream Codex profile. Fully exit the official chatgpt process
before starting codex-desktop, and vice versa. Their packages and desktop
entries can coexist, but upstream single-instance locking prevents reliable
parallel sessions.
In the desktop menu, the custom build is ChatGPT Community with a blue C;
the unqualified ChatGPT entry is OpenAI's package.
The first Community launch after migrating from the legacy pre-official build
refreshes cached Browser and Chrome plugins only when their bundled manifests
match the official Linux plugins and they contain a known retired Linux-port
marker. This one-time migration replaces the old custom Chrome extension host
and fixes the old /tmp/codex-browser-use-<uid> discovery path; the official
Linux runtime uses /tmp/codex-browser-use. It also removes legacy group-write
permission from the private .plugin-appserver runtime directory, which the
Chrome host rejects as an untrusted parent path.
If Browser was already loaded before that migration ran, fully exit every ChatGPT process, fully exit Chrome/Chromium, start ChatGPT Community, and then reopen the browser. Arbitrary plugin caches and user-authored plugins are never rewritten.
Clearing the entire browser profile or all Codex plugin caches is not a normal repair step. The official Browser/Chrome integration is already present in the Linux payload; this migration only replaces known snapshots created by the old community port.
If the legacy snapshot predates the recognized migration markers, remove only the two re-creatable upstream-bundled caches, then restart Community followed by Chrome:
pkill -TERM -x ChatGPT 2>/dev/null || true
rm -rf -- \
"${CODEX_HOME:-$HOME/.codex}/plugins/cache/openai-bundled/browser" \
"${CODEX_HOME:-$HOME/.codex}/plugins/cache/openai-bundled/chrome"
chmod go-w "${CODEX_HOME:-$HOME/.codex}/plugins/.plugin-appserver" 2>/dev/null || trueDo not delete the whole plugins directory: it may contain user plugins and
unrelated cached integrations.
Disable the feature in linux-features/features.json and rebuild to confirm the
official baseline. Enabled feature drift deliberately blocks candidate
promotion. Report the feature ID, package version/architecture, and patch report.
Known retired feature IDs are ignored. A misspelled or arbitrary unknown ID is an error; correct the config rather than adding a compatibility alias.
codex-update-manager status
systemctl --user status codex-update-manager.serviceWaitingForAppExit is expected: close all ChatGPT/Codex desktop processes. For
a failed privileged install, run codex-update-manager install-ready after
fixing the reported package-manager issue. Roll back with
codex-update-manager rollback.
Collect a useful updater report with:
codex-update-manager diagnose --json
journalctl --user -u codex-update-manager.service -n 200 --no-pagerStart by separating staging from packaging:
make build-app
make packageIf staging passes but packaging fails, confirm the distribution builder is
installed and inspect the final lines for the selected deb/RPM/pacman command.
If sudo-created files from an old checkout block cleanup, use the exact backup
procedure below; do not rerun the whole build as root.
For constrained systems, limit parallel compilation and compression:
MAX_BUILD_THREADS=2 make install-nativeGenerated state may be removed and rebuilt:
make clean-dist
make build-app
make packageDo not delete the updater rollback artifact unless you intentionally give up the recovery path.
To remove only package artifacts, use make clean-dist. make clean-state is
more destructive: it removes updater config/state/cache and therefore its
managed rollback information.
codex-app.backup-* directories are generated transactional backups, not
source files or additional installed applications. A backup created by an old
root-run build may be owned by root. Current builds collapse that cleanup
failure to one warning and continue with the accepted candidate.
Inspect the exact stale directories before changing or deleting anything:
find "$PWD" -maxdepth 1 -type d -name 'codex-app.backup-*' -printFor a confirmed stale path, replace /absolute/path/to/backup below with one
exact path printed above:
sudo chown -R -- "$(id -u):$(id -g)" /absolute/path/to/backup
rm -rf -- /absolute/path/to/backupNever run the cleanup against the repository root, codex-app/, the active
updater rollback artifact, $HOME, or a wildcard you have not inspected.