Skip to content

[Linux Desktop][26.924] Electron runtime replaces libuv's SIGCHLD handler with an empty function: children are never reaped, so shell env times out, "Git is unavailable", threads never load #48554

Closed

Description

@axusnetworks

Summary

On Linux, ChatGPT Desktop 26.924.20706 and 26.924.22138 install an empty SIGCHLD handler in the main (browser) process after startup, replacing libuv's handler. libuv installs its SIGCHLD handler only once, when the first child is spawned, so from that point no child process is ever reaped. Every child_process promise in the main process (and its worker threads) waits forever.

This appears to be the root cause of #48419, #48397, #48225 and #48417, and likely of #48482. The same mechanism as #38505 (zombie accumulation on macOS) may be involved there too.

Environment

  • ChatGPT Desktop 26.924.22138 (build 11645, build commit 2e782921399a788a842b74ee1944a2e1e6e003a1), official .deb, x86-64
  • Ubuntu 26.04, Linux kernel 7.0, KDE Plasma
  • 26.917.71314 is not affected. Both builds bundle libuv 1.52.1; the Electron ("owl") runtime archive changed between them.

Symptoms (all explained by the cause)

  • Failed to load shell env caller=startup detail="Timed out after 5000ms." on every start (the login-shell probe finishes in ~0.2 s when run by hand)
  • Worktree archive will be retried errorMessage="Git is unavailable" although git works (the Git availability probe never gets its exit status)
  • Opening a local thread: thread_hydration ... outcome=failure reason=timeout; hydration stops after metadata_ready because prepare() awaits child processes; thread/resume is never sent
  • New messages are queued and new threads never start
  • ps shows zombie (Z) children of the ChatGPT main process: bash, git, ps, gh, tar, codex, growing over time

Evidence

  1. Zombies: ps -o pid,stat,comm --ppid <ChatGPT main pid> lists Z children for every short-lived helper.
  2. SIGCHLD delivered, nothing reaps it: a bpftrace probe on signal:signal_deliver (sig 17) for the main process shows SIGCHLD delivered to the main thread. No wait4/waitid follows, and the handler writes nothing to libuv's signal pipe.
  3. The installed handler is empty: the sa_handler address resolves to a CFI jump-table entry (0x117d9f78 in the 26.924.22138 ChatGPT binary), which jumps to an identical-code-folded empty function at 0x11ce69c8 (push rbp; mov rbp,rsp; pop rbp; ret).
  4. Where it is installed: the function at 0x723eb00 calls an initializer (0x723eb70). When that returns 0, it calls sigaction(17 /*SIGCHLD*/, {sa_handler = <empty>, sa_flags = 0}, NULL). The function is reached through pointers in .data.rel.ro (0x1244c698, 0x1244c758), i.e. a vtable. Addresses are virtual addresses in the unmodified 26.924.22138 binary.
  5. Knock-on effect: in the broken state SigCgt of the main process stays at 0x17381ecff. execa's signal-exit hooks remain registered because no child ever exits. With the fix below it returns to 0x1000104c8.

Controlled A/B test

Isolated headless instances of the installed build (Xvfb, private CODEX_HOME, Electron user data dir and TMPDIR, private copy of the bundled codex, no sign-in), 60 s each:

zombie children shell env app-server
stock 4-5 and rising Failed to load shell env connected
with preload guard 0 loads connected

On the real signed-in profile with the guard: saved threads render (including one with ~1,400 prior messages), messages send, new threads start, and 0 unreaped children remain after hours of use.

Workaround (no downgrade)

Preload a small library that refuses only a sigaction(SIGCHLD) call whose handler is an empty function while a real handler is already installed. Every other call passes through, and the library strips itself from LD_PRELOAD so child processes don't inherit it. Launch with LD_PRELOAD=/path/to/sigchld-guard.so /usr/lib/chatgpt/ChatGPT. Don't launch through the chatgpt shell wrapper: the wrapper's sh loads the library first, and the library removes the variable before the app starts. Build with gcc -O2 -fPIC -shared -o sigchld-guard.so sigchld-guard.c -ldl.

sigchld-guard.c (x86-64)
#define _GNU_SOURCE
#include <dlfcn.h>
#include <signal.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

typedef int (*sigaction_fn)(int, const struct sigaction *, struct sigaction *);

static sigaction_fn real_sigaction;

static sigaction_fn resolve(void)
{
    if (real_sigaction == NULL)
        real_sigaction = (sigaction_fn)dlsym(RTLD_NEXT, "sigaction");
    return real_sigaction;
}

/* Follow endbr64 and direct jumps (CFI jump tables) to the function body. */
static const unsigned char *body(const unsigned char *p)
{
    for (int hops = 0; hops < 4; hops++) {
        if (p[0] == 0xf3 && p[1] == 0x0f && p[2] == 0x1e && p[3] == 0xfa)
            p += 4;
        if (p[0] == 0xe9) {
            int32_t rel;
            memcpy(&rel, p + 1, sizeof rel);
            p += 5 + rel;
        } else if (p[0] == 0xeb) {
            p += 2 + (int8_t)p[1];
        } else {
            break;
        }
    }
    return p;
}

static int is_empty_function(void (*handler)(int))
{
    static const unsigned char framed_ret[] = {0x55, 0x48, 0x89, 0xe5, 0x5d, 0xc3};
    const unsigned char *p = body((const unsigned char *)handler);
    return p[0] == 0xc3 || memcmp(p, framed_ret, sizeof framed_ret) == 0;
}

static int is_real_handler(const struct sigaction *sa)
{
    if (sa->sa_flags & SA_SIGINFO)
        return sa->sa_sigaction != NULL;
    return sa->sa_handler != SIG_DFL && sa->sa_handler != SIG_IGN;
}

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
{
    sigaction_fn next = resolve();
    if (next == NULL)
        return -1;
    if (signum == SIGCHLD && act != NULL && !(act->sa_flags & SA_SIGINFO)
            && is_real_handler(act) && is_empty_function(act->sa_handler)) {
        struct sigaction current;
        if (next(SIGCHLD, NULL, &current) == 0 && is_real_handler(&current)) {
            if (oldact != NULL)
                *oldact = current;
            return 0;
        }
    }
    return next(signum, act, oldact);
}

__attribute__((constructor)) static void drop_from_environment(void)
{
    resolve();
    unsetenv("LD_PRELOAD");
}

Suggested fix

Don't install a SIGCHLD handler in the Electron runtime after Node/libuv has installed one. Or save and chain to the previous handler, or install it before Node's first spawn. The installer at 0x723eb00 appears to be new in the runtime shipped with 26.924.x.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    on Sep 26, 2026
  2. jointsome0-lgtm commented on Sep 27, 2026

    @jointsome0-lgtm

    Independent confirmation, plus a handoff procedure for another affected laptop.

    We diagnosed and repaired the same failure on September 26, before finding this issue. On ChatGPT Desktop 26.924.22138, Linux x86-64, kernel 7.0.0-34-generic:

    • All local Work/Codex chats stayed loading. Ordinary ChatGPT chats loaded.
    • Reinstalling/upgrading the package and clearing only the HTTP/code caches did not resolve it.
    • Direct app-server requests could read the local thread history.
    • bundled_plugins_reconcile_started had no corresponding completion or failure. Instrumentation narrowed the pending await to the ps invocation in browser native-host cleanup.
    • The main process retained zombie bash, git, ps, and other children. A Node SIGCHLD listener received no callback, including after explicitly sending SIGCHLD.
    • A small N-API probe showed different installed handlers for SIGCHLD and a freshly registered Node SIGWINCH listener.

    Restoring Node/libuv's handler for SIGCHLD in the running process immediately released the pending waits. Plugin reconciliation completed, child_process.execFile('/usr/bin/git', ['--version']) returned successfully, and the user confirmed that the local chat opened and displayed messages. After installing the workaround and restarting the normal app, reconciliation completed again and no zombie children appeared in the final process check. No conversation history or authentication state was deleted.

    We did not trace the code which installed the conflicting handler. The binary-level investigation in the issue above supplies evidence beyond our own test.

    Instructions for an affected second laptop

    The same visible symptom on a second laptop is not yet confirmation of this mechanism. These instructions can be handed to Codex CLI in a terminal, independently of the broken Desktop UI.

    1. Record the installed build and identify the main process. On a Debian package installation:

      dpkg-query -W -f='${Version}\n' chatgpt
      uname -mprs
      ps -C ChatGPT -o pid,ppid,stat,args

      Select the main executable process without a --type=... argument. Inspect its children using ps --ppid MAIN_PID -o pid,ppid,stat,etime,comm. Confirm that short-lived helpers remain in state Z across repeated observations. Look for the shell-environment timeout and a plugin-reconciliation start without completion in the Desktop logs. Redact paths and account/session identifiers before publishing logs.

    2. Check whether an upstream update already fixes it. Do not apply a build-specific workaround to an unrelated version or architecture merely because a chat is loading slowly.

    3. Choose one workaround, with a backup. The issue body above provides a complete x86-64 preload-guard source and build command:

      gcc -O2 -fPIC -shared -o sigchld-guard.so sigchld-guard.c -ldl

      Save and review the source from the issue body before compiling. Build it in a dedicated user-owned repair directory. That guard is the original reporter's tested workaround; our independent test used the N-API restoration described below. They are alternative approaches, not two patches to stack.

    4. For the preload guard, quit only Desktop, then test a direct executable launch. Preserve any ongoing standalone Codex/Claude CLI sessions. Confirm the executable path on that laptop. For the package path in this report:

      LD_PRELOAD=/absolute/path/to/sigchld-guard.so /usr/lib/chatgpt/ChatGPT

      Use the actual executable, not /usr/bin/chatgpt, because the shell wrapper can consume the guard's one-process environment setup. If LD_PRELOAD is already configured, investigate it before replacing it. Do not add the guard to /etc/ld.so.preload or a global shell environment.

    5. Verify the outcome before making the launcher persistent. Open an existing local chat, confirm that its messages render, check that plugin reconciliation completes, and inspect the main process for accumulating zombie children. Verify Git availability through Desktop. If the test succeeds, a dedicated user launcher can set LD_PRELOAD for that executable only. Keep the original launcher available.

    6. Rollback and updates. For the preload approach, quit Desktop and use its original launcher without the guard. Remove the dedicated launcher if one was created. Recheck the unmodified app after an upstream update before carrying the workaround forward. If instead modifying app.asar, retain the exact original, check its version/hash before patching, and restore it only to the matching build.

    The independently tested restoration mechanism

    Our local patch used a short main-process bootstrap and an N-API addon, scoped to the Desktop process. The essential native operation was:

    struct sigaction node_action;
    if (sigaction(SIGWINCH, NULL, &node_action) != 0)
        return; /* Report failure to the caller. */
    if (node_action.sa_handler == SIG_DFL || node_action.sa_handler == SIG_IGN)
        return; /* The temporary Node listener was not established. */
    if (sigaction(SIGCHLD, &node_action, NULL) != 0)
        return; /* Report failure to the caller. */
    raise(SIGCHLD);

    The bootstrap first registered a temporary process.on('SIGWINCH', listener) to obtain Node/libuv's handler, called the addon, then removed that exact temporary listener in finally. This snippet describes the mechanism, not a standalone installer. It must execute inside the affected main process. Running it in a separate node process does not repair Desktop.

    The final local patch had no inspector or remote-debugging port. It did not disable plugin checking or bypass its waits. Initial shell-environment hydration happened before our bootstrap and could still incur its five-second timeout, so our patch was a recovery workaround rather than a complete upstream fix.

    Paste-ready task for Codex on the second laptop

    Investigate local Desktop chats stuck loading using #48554 and this comment. First verify the installed version, architecture, main-process zombie children, and plugin-reconciliation logs. Do not assume the diagnosis from the spinner alone. Preserve chats, credentials, and active standalone CLI sessions. If this SIGCHLD regression is confirmed and no fixed update is available, review and build the issue's scoped preload guard, test a direct Desktop executable launch, and verify an existing local chat plus child-process completion. Only persist the launcher after the test succeeds. Save the original launcher and explicit rollback instructions. Distinguish results actually tested on this laptop from the reports above.

  3. beyondfashion-ai commented on Sep 27, 2026

    @beyondfashion-ai

    Confirming on WSL2 (Ubuntu 24.04 "noble" under WSL2 on Windows, X11 --ozone-platform=x11, official .deb). Same regression on 26.924.20706 and 26.924.22138; 26.917.71314 works. Adding a few data points that may help narrow it down.

    Zombie accumulation (main process children)

    • 26.924.22138, 60 s after a clean start (after apt purge + reinstall + a brand-new empty profile dir): 8–11 <defunct> children of the main ChatGPT process (git, gh, bash, ps, codex).
    • 26.917.71314 after downgrade, same machine/profile/~/.codex: 0 zombies.

    Where resume stalls (renderer side, traced with CDP logpoints)

    • maybe_resume_started → readThread → writable roots → resumeState=resuming → metadata_ready → prepare() → thread-start config builder.
    • Inside the builder, fetchProxyConfig (get-copilot-api-proxy-info) returns in ~290 ms, but fetchCodexConfig → main-process IPC mcp-codex-config never resolves (tested with several different cwd values, including /tmp). thread/resume is therefore never sent.
    • In the main process, buildMcpCodexConfig awaits the browser-use/bundled-plugin sync state before returning. On 26.924 the log shows bundled_plugins_reconcile_started but never bundled_plugins_reconcile_completed; on 26.917 it completes. This fits the unreaped-child explanation above: the reconcile, shell-env probe and git probe all wait on child exit events that never arrive.

    Things that did NOT help on 26.924 (ruled out)

    • Removing stale queued follow-ups (queue_1.sqlite and queued-follow-ups in .codex-global-state.json)
    • Removing an unknown [features] key from config.toml
    • Disabling auto-connect for an offline SSH remote host
    • Upgrading 26.924.20706 → 26.924.22138
    • Full purge/reinstall with a fresh profile directory

    Downgrade note
    26.924 applies new SQLite migrations on first start (state_5.sqlite v56–57, thread_history_1.sqlite v7, codex-dev.db 20260914…/20260924…). 26.917.71314 still started fine against the migrated DBs here and resumed threads normally, but back up ~/.codex/*.sqlite and ~/.codex/sqlite/ before downgrading. Workaround used:

    sudo apt-get install --allow-downgrades ./chatgpt_26.917.71314_amd64.deb
    sudo apt-mark hold chatgpt   # otherwise unattended-upgrades re-installs 26.924 the next morning

    Mobile remote-control and the standalone CLI (codex resume <id>, 0.157.1) kept working against the same threads throughout, consistent with the problem being confined to the desktop main process.

  4. Zburatorul commented on Sep 27, 2026

    @Zburatorul

    Confirming on Debian 13 (x86-64, X11), 26.924.20706 and 26.924.22138; 26.917.71314 is unaffected. One addition that I think changes where the regression is: 26.917.71314 installs the same empty SIGCHLD handler. What changed in 26.924 is when the first child process is spawned relative to that sigaction call.

    I ran A/B traces of both builds under identical isolation: unpacked .deb, Xvfb, private D-Bus, throwaway HOME/XDG dirs, CODEX_HOME and --user-data-dir, no sign-in. The command was strace -f -e trace=rt_sigaction,wait4,clone,clone3,execve -e signal=SIGCHLD. Times are relative to process start.

    empty SIGCHLD handler installed first child spawn (libuv installs uv__signal_handler) handler that ends up active zombies
    26.917.71314 t+0.67s t+7.2s libuv (installed last) 0
    26.924.22138 t+0.42s t+0.40s, the shell-env bash -ilc probe the empty one (overwrites libuv 20ms later) yes, from the first child on

    Both builds point SIGCHLD at the same kind of CFI jump-table slot, 0xd8 below libuv's handler, jumping to the same folded empty function (push rbp; mov rbp,rsp; pop rbp; ret):

    • 26.917.71314 ChatGPT: slot 0x118268c8 → jmp 0x11c3a198 (empty); libuv handler 0x118269a0
    • 26.924.22138 ChatGPT: slot 0x117d9f78 → jmp 0x11ce69c8 (empty); libuv handler 0x117da050

    In 26.917 the empty handler is harmless: libuv installs its handler afterwards, on the first spawn. In 26.924, the reworked startup (early-bootstrap.js → shell-env hydration) spawns bash before the native code runs. libuv only installs its handler once, so it never recovers.

    This suggests two independent fixes:

    • Native: don't overwrite an existing SIGCHLD disposition (check it with sigaction(SIGCHLD, NULL, &old), or chain to the old handler). This is what the preload guard above emulates.
    • JS / startup order: don't spawn children before that native initialization has run, as in 26.917.

    Either one alone should restore reaping. A startup self-check (spawn true, assert exit arrives) would catch this class of regression.

    strace, 26.924.22138 (main process, SIGCHLD-related)
    2772519 20:31:31.294422 rt_sigaction(SIGCHLD, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f7f1e84bd70}, NULL, 8) = 0
    2772519 20:31:31.692833 rt_sigaction(SIGCHLD, {sa_handler=0x564b6de2c050, sa_mask=~[RTMIN RT_1], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f7f1e84bd70}, NULL, 8) = 0
    2772519 20:31:31.692931 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f7f1d5b3710) = 2772557
    2772519 20:31:31.712523 rt_sigaction(SIGCHLD, {sa_handler=0x564b6de2bf78, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f7f1e84bd70}, NULL, 8) = 0
    2772519 20:31:31.735092 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=2772557, si_uid=1000, si_status=0, si_utime=0, si_stime=1 /* 0.01 s */} ---
    # 2772557 = execve("/bin/bash", ["/bin/bash", "-ilc", "printf '\\0%s\\0' '_SHELL_ENV_DELI"...]) -> exited with 0 at 20:31:31.733985
    # no wait4()/waitid() for it (or for later children) anywhere in the trace; load base 0x564b5c652000
    
    strace, 26.917.71314 (main process, SIGCHLD-related)
    2777394 20:36:43.919568 rt_sigaction(SIGCHLD, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fc11d04bd70}, NULL, 8) = 0
    2777394 20:36:44.588015 rt_sigaction(SIGCHLD, {sa_handler=0x55c427e248c8, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fc11d04bd70}, NULL, 8) = 0
    2777394 20:36:51.139984 rt_sigaction(SIGCHLD, {sa_handler=0x55c427e249a0, sa_mask=~[RTMIN RT_1], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7fc11d04bd70}, NULL, 8) = 0
    2777394 20:36:51.249225 wait4(2777643, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG, NULL) = 2777643
    
  5. ChrisLauinger77 commented on Sep 27, 2026

    @ChrisLauinger77

    Another reproduction: ChatGPT Desktop for Linux 26.924.22138 on Debian forky/sid. Since the September 26 update, new Codex and Work local tasks stay at ‘Your task is being started’ indefinitely. Git works locally (/usr/bin/git, version 2.53.0), but desktop logs show a 5-second shell environment timeout and repeated ‘Git is unavailable’ messages. The standalone Codex CLI works. I have not tested the SIGCHLD mechanism.

  6. jasonsperske commented on Sep 27, 2026

    @jasonsperske

    Confirming on Ubuntu 26.04.1 LTS, kernel 7.0.0-34-generic, x86-64, X11, official .deb via the auto-configured apt repo. Installed package: chatgpt 26.924.20706 (bundled app-server 0.158.0-alpha.2). Everything matches the mechanism described here.

    Timeline (from /var/log/dpkg.log and ~/.codex/logs_2.sqlite)

    • 2026-09-25 22:48–22:50 local time: last turn worked on 26.901.51231
    • 2026-09-25 22:57: apt auto-upgrade 26.901.51231 → 26.924.20706; on next launch, state DB migrations 53–57 and thread-history migration 7 all applied successfully
    • Since then: zero thread/start, thread/resume or turn/start requests have reached the app-server. Existing local threads spin forever. New tasks sit at "Starting your task", and follow-up messages stay queued.
    • Signing out and back in, restarting, and clearing a stale chatgpt-conversation-resume-tokens-v1 entry had no effect.

    Zombies and signal mask (40 s after a normal launch)

    $ ps -o pid,stat,comm --ppid <ChatGPT main pid> | awk 'NR==1||$2 ~ /Z/'
        PID STAT COMMAND
      64527 Z    bash
      64882 Z    codex
      65114 Z    git
      65199 Z    ps
      65226 Z    ps
      65286 Z    gh
      65484 Z    ps
      65516 Z    git
      65642 Z    ps
      65643 Z    git
    $ grep SigCgt /proc/<pid>/status
    SigCgt:	000000017381ecff
    

    This is the same SigCgt value reported above for the broken state.

    Main-process stdout (launched from a terminal)

    Failed to load shell env caller=startup detail="Timed out after 5000ms." durationMs=5015 ... status=timed_out timeoutMs=5000
    [managed-worktree-archive-queue] Worktree archive will be retried errorMessage="Git is unavailable" ... phase=queued
    

    bash -ilc true takes 0.20 s by hand, and /usr/bin/git 2.53.0 works.

    Renderer vs. app-server (CDP on the main window, plus app-server TRACE logs)

    • The renderer logs maybe_resume_started connectedEnvironmentIds=undefined environmentIds=undefined previousResumeState=needs_resume vmEvent=thread_resume_requested for each thread I open.
    • The app-server receives and answers thread/list, thread/read, thread/attachment/list, thread/queue/list and configRequirements/read in 2–5 ms. It never receives thread/resume, even with TRACE logging.
    • client.performance.span name=thread_navigation outcome=aborted reason=superseded threadState=cold, with marks stopping at hydration_started.
    • There are no renderer exceptions or console errors. The page just waits.
    • On-disk data is intact: every thread_history_projection_state.next_rollout_byte_offset equals its rollout file's size, and rollout_migration_skipped_rollouts is empty.

    Happy to run a strace or GDB A/B test if it would help. The SigCgt value and zombie list alone seem enough to show it's the same defect.

  7. daseus commented on Sep 27, 2026

    @daseus

    Another independent confirmation on KDE neon, x86-64, native Wayland.

    I could neither open previous conversations nor start new ones in the ChatGPT desktop app. Both Codex and Work were affected. The standalone Codex CLI continued working normally.

    We reproduced this with both 26.924.20706 and 26.924.22138. The local backend could list and read existing conversations, but opening them in the app never reached thread/resume. The logs showed the same five-second shell timeout and “Git is unavailable” errors. Completed bash, git, and ps processes remained as zombies under the desktop process, even though they had exited successfully.

    What got me working again:

    • Rolled the desktop back to 26.908.70816, which restored conversation loading and new chats.
    • That version's bundled backend lacked GPT-6 Sol, my default model. We configured the working desktop to use my installed Codex CLI 0.157.1 through CODEX_CLI_PATH.
    • Verified new Codex and Work chats with GPT-6 Sol, a shell tool call, reopening saved chats, and continuing a reopened conversation.

    My local history was preserved; no profile reset or history deletion was needed. We did not trace the SIGCHLD handler itself, so this confirms the matching symptoms and affected versions, rather than independently proving that exact mechanism.

  8. sonytalk-W commented on Sep 27, 2026

    @sonytalk-W

    Independent reproduction on Ubuntu Linux with the official chatgpt Debian package 26.924.22138 (build 11645, commit 2e782921399a788a842b74ee1944a2e1e6e003a1). Kernel: 7.0.0-34-generic, x86_64. Bundled runtime identifies as owl; its version file reports 42.3.0.

    User-visible reproduction

    1. Launch the desktop app and open a new chat.
    2. Send a minimal prompt asking it to reply only with “OK”.
    3. No reply arrives. The same failure persists after restarting the app.

    A first-response telemetry event recorded outcome=failure reason=timeout durationMs=120013. Background configuration requests and account event subscriptions still worked.

    Independent process-level evidence

    • Startup consistently reports Failed to load shell env ... Timed out after 5000ms and Git is unavailable.
    • /usr/bin/git --version succeeds outside the app (git version 2.53.0).
    • The equivalent interactive login-shell environment capture, including the app's delimiters and shell-probe environment flags, succeeds outside the app in 0.164 seconds.
    • Completed bash, git, gh, and ps children accumulate in zombie state beneath the desktop main process.
    • A bounded strace -f -tt -e trace=process capture on 2026-09-27 confirmed:
    26854 20:02:42.440002 exit_group(0)
    26833 20:02:42.440635 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED,
                                  si_pid=26854, si_uid=1000, si_status=0, ...} ---
    

    Parent PID 26833 did not reap child 26854 during the capture, and the child remained a zombie. Two Git children likewise exited with status 0 and remained zombies:

    27164 20:02:49.373740 exit_group(0)
    27261 20:02:52.254724 exit_group(0)
    

    In an earlier run, explicitly delivering SIGCHLD to the desktop main process did not reap its 12 existing zombie children. The observed main-process SigCgt was 000000017381ecff, matching the broken-state mask described above.

    This independently corroborates successful child execution, SIGCHLD delivery, and failed completion/reaping on another installation. We did not trace handler registration or test the preload workaround, so this comment does not independently establish the handler-overwrite mechanism or claim a successful fix. No app binaries, user settings, or conversation data were modified. The tracer has been stopped and detached.

  9. Dango233 commented on Sep 27, 2026

    @Dango233

    Adding confirmation on ARM64 / aarch64: Ubuntu 24.04 running under PRoot on Android, using the official ChatGPT Linux package, an X11/Xvfb desktop, and --no-sandbox --disable-gpu.

    26.924.22138 reproduced the failure; 26.917.71314 restored normal loading on rollback. This adds another environment to the existing Linux reports, rather than establishing a PRoot-specific bug.

    Observed in the affected version:

    • Existing local Codex conversations remained on a spinner. thread/read succeeded, but loading did not reach a thread/resume request.
    • The SSH connection UI also appeared unresponsive: catalog logs showed refresh_started without completion.
    • Terminated bash, ssh, git, and codex children remained zombies under the desktop main process.
    • Local SQLite PRAGMA quick_check checks returned ok; standalone ssh -G and Node subprocess tests completed.

    Local SIGCHLD instrumentation observed one handler registration followed by a different registration during startup (SA_RESTART first, flags 0 later). We did not symbolize the ARM64 handlers, so their precise identities are not independently established by our trace. Both bundled runtimes passed minimal subprocess tests when helpers were first spawned after app.whenReady(); the older runtime with newer application resources still reproduced the failure.

    We tested the same early-bootstrap deferral described in the Gentoo comment on #48212:

    - async function o(){await t.a();
    + async function o(){await n.app.whenReady();await t.a();

    The remaining startup and permission/policy initialization calls were retained, with the ASAR metadata updated accordingly.

    With the existing profile, SSH catalog load_completed / refresh_completed returned, and an existing local conversation rendered successfully. thread/resume completed in 837 ms in the test copy and 1255 ms in the patched installed package, followed by maybe_resume_success. No zombie direct children were observed at the follow-up checks.

    This supports the startup-order diagnosis and extends the workaround evidence to Android-hosted ARM64 PRoot. It is a local diagnostic workaround, not a validated production fix: we verified existing conversation loading and SSH catalog refresh, but did not validate a new SSH connection, a new agent turn, or long-running stability. GPU rendering artifacts were a separate issue; disabling GPU acceleration alone did not resolve the loading failure.

    Diagnosis and drafting were assisted by Codex; observations come from executed local checks and application logs. No device branding, private addresses, account/session identifiers, or conversation contents are included.

  10. WaterWhisperer commented on Sep 27, 2026

    @WaterWhisperer

    Update: confirmed that downgrading from 26.924.22138 to 26.917.71314 fixes the issue on Ubuntu 24.04 x86_64. Existing conversations load and accept messages again, and the model selector is restored. No profile/cache/config data was cleared; only the package version changed.

    Reproduced on Ubuntu 24.04 x86_64 with ChatGPT Desktop 26.924.22138.
    Existing conversations do not load normally. They only become visible after opening “View activity”, but I cannot continue sending messages in existing conversations. The model selector/tab is also missing.
    My APT cache still contains 26.917.71314, so I’m downgrading to that version now. I’ll update this comment if the rollback fixes the issue.

  11. SoongVilda commented on Sep 27, 2026

    @SoongVilda

    I’m also affected on CachyOS (Arch-based), x86_64, and the preload workaround described in this issue works for me.

    Environment:

    • Package: chatgpt-bin 26.924.22138-1 from the openai-chatgpt repository
    • Desktop: KDE Plasma / Wayland
    • Shell: fish

    For reproducibility, below is the source I used to build sigchld-guard.so, followed by the build and launch commands.

    Full guard source and build instructions (x86-64)

    Create the directory:

    mkdir -p "$HOME/.local/lib/chatgpt-sigchld"

    Save the following as ~/.local/lib/chatgpt-sigchld/sigchld-guard.c:

    #define _GNU_SOURCE
    #include <dlfcn.h>
    #include <signal.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef int (*sigaction_fn)(int, const struct sigaction *,
                                struct sigaction *);
    
    static sigaction_fn real_sigaction;
    
    static sigaction_fn resolve_sigaction(void)
    {
        if (!real_sigaction)
            real_sigaction = (sigaction_fn)dlsym(RTLD_NEXT, "sigaction");
    
        return real_sigaction;
    }
    
    static const unsigned char *function_body(const unsigned char *p)
    {
        for (int i = 0; i < 4; ++i) {
            /* endbr64 */
            if (p[0] == 0xf3 && p[1] == 0x0f &&
                p[2] == 0x1e && p[3] == 0xfa)
                p += 4;
    
            /* jmp rel32 */
            if (p[0] == 0xe9) {
                int32_t rel;
                memcpy(&rel, p + 1, sizeof(rel));
                p += 5 + rel;
                continue;
            }
    
            /* jmp rel8 */
            if (p[0] == 0xeb) {
                int8_t rel = (int8_t)p[1];
                p += 2 + rel;
                continue;
            }
    
            break;
        }
    
        return p;
    }
    
    static int empty_handler(void (*handler)(int))
    {
        static const unsigned char empty_framed[] = {
            0x55, 0x48, 0x89, 0xe5, 0x5d, 0xc3
        };
    
        const unsigned char *p =
            function_body((const unsigned char *)handler);
    
        return p[0] == 0xc3 ||
               memcmp(p, empty_framed, sizeof(empty_framed)) == 0;
    }
    
    static int real_handler(const struct sigaction *sa)
    {
        if (sa->sa_flags & SA_SIGINFO)
            return sa->sa_sigaction != NULL;
    
        return sa->sa_handler != SIG_DFL &&
               sa->sa_handler != SIG_IGN;
    }
    
    int sigaction(int signum,
                  const struct sigaction *act,
                  struct sigaction *oldact)
    {
        sigaction_fn next = resolve_sigaction();
    
        if (!next)
            return -1;
    
        if (signum == SIGCHLD &&
            act &&
            !(act->sa_flags & SA_SIGINFO) &&
            real_handler(act) &&
            empty_handler(act->sa_handler)) {
    
            struct sigaction current;
    
            if (next(SIGCHLD, NULL, &current) == 0 &&
                real_handler(&current)) {
    
                if (oldact)
                    *oldact = current;
    
                return 0;
            }
        }
    
        return next(signum, act, oldact);
    }
    
    /*
     * Don't let normal children launched by ChatGPT inherit the preload.
     * The library itself remains loaded in the current ChatGPT process.
     */
    __attribute__((constructor))
    static void init(void)
    {
        resolve_sigaction();
        unsetenv("LD_PRELOAD");
    }

    Compile it with GCC:

    gcc -O2 -fPIC -shared -Wall -Wextra \
        -o "$HOME/.local/lib/chatgpt-sigchld/sigchld-guard.so" \
        "$HOME/.local/lib/chatgpt-sigchld/sigchld-guard.c" \
        -ldl

    Check the generated library:

    file "$HOME/.local/lib/chatgpt-sigchld/sigchld-guard.so"

    It should report an ELF 64-bit x86-64 shared object. Only continue if compilation succeeded.

    After compiling, I fully quit ChatGPT, including any background instance, and launch the actual executable directly:

    env LD_PRELOAD="$HOME/.local/lib/chatgpt-sigchld/sigchld-guard.so" \
        /usr/lib/chatgpt/ChatGPT --ozone-platform=wayland

    The Wayland option matches my desktop setup.

    The wrapper warning also applies to this package: /usr/bin/chatgpt resolves to a shell launcher, so the preload must be applied directly to /usr/lib/chatgpt/ChatGPT. Otherwise, the wrapper loads the guard and clears LD_PRELOAD before ChatGPT starts.

    I’m using this only as a temporary, manually triggered workaround for 26.924.22138-1, without modifying the installed package or desktop launcher. The guard uses x86-64 instruction matching and should be reassessed after an update. Clearing LD_PRELOAD prevents normal propagation to newly executed programs; fork-only children still inherit the loaded library.

  12. 0xtaruhi commented on Sep 27, 2026

    @0xtaruhi

    Independent confirmation of the managed-SSH impact and a successful no-downgrade workaround on Fedora 44 x86-64.

    • Desktop RPM: chatgpt-26.924.22138-1.x86_64. Remote: Ubuntu 26.04 over SSH.
    • Before the workaround, the app reported SSH: local ssh config probe timed out after 5000ms and SSH: codex path probe timed out after 60000ms. Direct SSH and remote codex --version returned promptly. Short-lived ssh, git, zsh, and ps children remained as zombies under the desktop main process.
    • I independently checked the installed binary: the CFI slot at 0x117d9f78 jumps to the empty function at 0x11ce69c8 (push rbp; mov rbp,rsp; pop rbp; ret), matching this issue's analysis.
    • With the x86-64 SIGCHLD preload guard from this issue, the same installed 26.924 build and existing profile worked without a downgrade or profile reset. The shell-environment probe completed with status=loaded in 144 ms; remote login-shell commands completed in about 0.76–0.80 s; and the managed remote connection transitioned from connecting to connected. The SSH process stayed up running codex app-server proxy, and there were 0 zombie children at a follow-up check after more than a minute.

    This adds end-to-end validation of a managed SSH connection, beyond SSH catalog refresh. Account identifiers, host addresses, and project paths are omitted.

  13. 18 remaining items

  14. DenislavVelichkov commented on Sep 28, 2026

    @DenislavVelichkov

    Proposed upstream runtime change for this SIGCHLD regression. The diff targets chrome/browser/chrome_browser_main_posix.cc from Chromium 154.0.8037.57, for application in OpenAI's Linux desktop runtime tree.

    Chromium's placeholder handler has a purpose when SIGCHLD is default, ignored, or configured with SA_NOCLDWAIT: it allows later waits on children. The regression occurs when libuv already installed a waitable SIGCHLD handler and Chromium unconditionally replaces it. This change keeps the existing handler in that case, while retaining Chromium's placeholder for the other dispositions.

    diff --git a/chrome/browser/chrome_browser_main_posix.cc b/chrome/browser/chrome_browser_main_posix.cc
    index 925f2a7..0b16468 100644
    --- a/chrome/browser/chrome_browser_main_posix.cc
    +++ b/chrome/browser/chrome_browser_main_posix.cc
    @@ -151,6 +151,18 @@ int ChromeBrowserMainPartsPosix::PreEarlyInitialization() {
       if (result != content::RESULT_CODE_NORMAL_EXIT)
         return result;
     
    +#if BUILDFLAG(IS_LINUX)
    +  // An embedder may already have installed a SIGCHLD handler (e.g. libuv).
    +  // Replacing it would prevent the embedder from observing child exits.
    +  struct sigaction current_action = {};
    +  CHECK_EQ(0, sigaction(SIGCHLD, nullptr, &current_action));
    +  if (current_action.sa_handler != SIG_DFL &&
    +      current_action.sa_handler != SIG_IGN &&
    +      !(current_action.sa_flags & SA_NOCLDWAIT)) {
    +    return content::RESULT_CODE_NORMAL_EXIT;
    +  }
    +#endif
    +
       // We need to accept SIGCHLD, even though our handler is a no-op because
       // otherwise we cannot wait on children. (According to POSIX 2001.)
       struct sigaction action = {};

    Before release, please verify that a libuv SIGCHLD handler and its flags survive PreEarlyInitialization, child exit callbacks run, and no zombies accumulate. Verify the default, ignored, and SA_NOCLDWAIT cases still permit waitpid to reap a child. In the full Linux desktop app, check shell setup, Git availability, existing chat resume, and a new task.

    The query and subsequent registration are separate calls. The runtime build should ensure no concurrent signal registration occurs between them; if that cannot be guaranteed, also move the early shell probe until after Chromium initialization. This is a source patch proposal. I verified that it applies cleanly to the matching Chromium source, but I cannot build or test OpenAI's desktop runtime from the public repository. Independent process-level confirmation of the same failure is in #48618.

  15. ardaerturk commented on Sep 28, 2026

    @ardaerturk

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

    26.924.22138, build 11645, official amd64 .deb (verified from package metadata and logs).

    What subscription do you have?

    Azure OpenAI API provider.

    What platform is your computer?

    Ubuntu 24.04.4 LTS, kernel 7.0.0-1014-azure, x86-64; XFCE/X11 through TigerVNC on an Azure VM.

    What issue are you seeing?

    Existing threads stayed loading. Logs showed the 5000 ms shell-environment timeout and “Git is unavailable”; bash, git, ps, gh, and codex children remained zombies.

    What steps can reproduce the bug?

    Launch this build and open an existing local thread. Restarting the app, rebooting the VM, and reinstalling the same official package did not resolve it.

    What is the expected behavior?

    Existing thread history loads.

    Additional information

    The issue's SIGCHLD preload guard resolved this on the same build and profile:

    • Existing histories rendered; logs recorded thread_hydration outcome=success and maybe_resume_success.
    • bundled_plugins_reconcile_completed appeared; no zombie children remained at the follow-up check.
    • The guard was absent from the exec'd app-server's memory mappings.

    Applied through the desktop and systemd launch wrappers, gated to the package version and executable SHA-256. No packaged files, credentials, or history were reset; dpkg -V chatgpt reported no changes. New-task execution was not separately tested.

  16. jaenw commented on Sep 28, 2026

    @jaenw

    This completely broke the Linux desktop build for everyone, aren't there any E2E tests?!?!

    💩

  17. zyhe16 commented on Sep 28, 2026

    @zyhe16

    This completely broke the Linux desktop build for everyone, aren't there any E2E tests?!?!

    💩

    Agreed, I don't even understand how they can make such mistakes...

  18. iboware commented on Sep 28, 2026

    @iboware

    Fedora 44 reproduction and same-build recovery

    I reproduced this with the official chatgpt-26.924.22138-1.x86_64 RPM on Fedora 44. rpm -V chatgpt reports no modified package files.

    In the stock app, every local conversation I tried remained on the loading spinner. The app server returned successful thread/read responses, but the desktop never sent thread/resume. The main process retained exited bash, git, and ps children in zombie state. A fresh renderer profile and a phone hotspot did not change the behavior.

    For a controlled recovery check, I stopped one stock test instance and relaunched the same installed binary with the process-local SIGCHLD guard described in this issue, using the same renderer profile and Codex home. An existing conversation then rendered its saved messages. After the load, that main process had zero zombie direct children. The RPM and conversation databases were not patched or reset.

    This result supports the SIGCHLD handler ordering diagnosis on Fedora too. The old/new startup trace explains why the regression appeared in 26.924 even though the no-op handler also existed in the earlier build. I would fix the runtime by preserving a previously installed, waitable SIGCHLD handler, as in the proposed source change, or by moving the first child spawn after Chromium initialization.

    A useful release regression test would spawn a short-lived child on both sides of Chromium initialization, require Node's exit callback to run, and check that no zombie remains. The packaged Linux smoke test should then verify shell environment loading, Git detection, existing conversation resume, and starting a new local task.

  19. VirelNode commented on Sep 28, 2026

    @VirelNode

    Confirmed on Ubuntu 24.04.5 LTS, x86-64, official Desktop DEB 26.924.22138. Thank you @axusnetworks for identifying the handler overwrite and publishing the original guard approach.

    I published a build-scoped implementation, launcher, build instructions, and rollback steps for others experiencing the same failure:

    https://gist.github.com/VirelNode/805b5274e0b680f70180c36be7fff8b2

    Before: the local app-server initialized and answered metadata requests, but a simple GUI prompt remained at “Starting your task” without reaching thread/start. The shell probe timed out at 5 seconds, Git was reported unavailable despite working in the terminal, and completed helper processes remained zombies. A fresh Desktop restart reproduced it.

    After: with the guard and the same installed application/profile, a new GUI prompt completed. After quitting and launching again through the repaired desktop entry, the saved conversation opened (thread_hydration outcome=success, about 689 ms), and a follow-up GUI prompt completed too. The main process had zero zombie children at the follow-up check. The fresh-launch log had no shell-environment timeout or Git-unavailable error. The app-server did not inherit LD_PRELOAD.

    The launcher checks the installed executable SHA-256 before enabling the library:

    23b753552181a8ea661681256c2dbf993fea1285fbc5c824478bad9cbdd45c91

    The guard only rejects the verified empty-handler replacement at the matching executable offset/bytes, while preserving an existing real handler. The installed jump and empty function were checked with disassembly. All other sigaction calls pass through. The launcher runs the executable directly; the library removes its preload environment before helpers spawn. A different executable hash, missing guard, or pre-existing preload makes the launcher run without this workaround.

    No installed binary, app.asar, authentication, conversation history, or Codex configuration was patched/reset. Standalone terminal sessions remained running. The C source compiled with -Wall -Wextra -Werror; the published launcher passed shell syntax validation. The gist explains the small portability change from the tested absolute library path to a library beside the launcher.

    This is a temporary local workaround, not an official fix or a claim of full Desktop regression coverage. A permanent runtime fix is still needed. No private logs, conversation contents, machine identifiers, or credentials are included.

    Posted with the affected user's authorization; investigated and verified with Codex CLI.

  20. dimpy-cmd commented on Sep 28, 2026

    @dimpy-cmd

    Confirming that this bug still exists in the official Fedora RPM chatgpt-26.924.22138-1.x86_64, tested on September 28, 2026.

    Environment: Fedora 44, x86-64, kernel 7.2.7-200.fc44.x86_64, glibc 2.43-8.fc44. Desktop build 11645, commit 2e782921399a788a842b74ee1944a2e1e6e003a1.

    Observed in the stock build:

    • Existing local chats spin indefinitely; a new chat opens, but submitting a message remains at “Starting your task.”
    • The app-server can read saved conversation data, but desktop restoration stalls before dispatching thread/resume.
    • Logs report Failed to load shell env ... Timed out after 5000ms and Git is unavailable.
    • The same login-shell check completes in 0.19 seconds when run directly and finds Git normally.
    • Exited bash, git, and codex helpers remain zombie children of the desktop main process. Its SigCgt was 000000017381ecff.
    • Reinstallation and a backed-up temporary renderer-cache reset did not resolve the loading problem.

    Same-build workaround test: a process-local preload guard preserving an existing real SIGCHLD handler against replacement by an empty main-executable handler was compiled and tested, then used to restart the same installed binary with the existing profile. The guard logged that it prevented the replacement. Afterward:

    • An existing chat resumed successfully (thread/resume, 290 ms).
    • A subsequent navigation reported outcome=success, with content visible in approximately 656 ms.
    • No zombie direct children remained at the follow-up check.
    • The fresh launch recorded zero shell-environment timeout or Git-unavailable errors.

    This supports the reported SIGCHLD regression on Fedora 44. The workaround is temporary, scoped to the exact executable hash, and does not constitute an upstream fix. A complete new model-response turn was not separately verified during this test. No installed application files or conversation databases were patched by the workaround.

    Please keep this issue open until a corrected Linux desktop build is available. Posted at the affected user’s request; no private conversation contents, credentials, or raw logs are attached.

  21. ht-Leung commented on Sep 28, 2026

    @ht-Leung

    Additional independent confirmation on Ubuntu 22.04.5 LTS, x86-64, kernel 6.8.0-138-generic, diagnosed and repaired on 2026-09-28.

    Affected build: chatgpt 26.924.22138, bundled app-server 0.158.0-alpha.2.1. The installed executable's SHA-256 is 23b753552181a8ea661681256c2dbf993fea1285fbc5c824478bad9cbdd45c91.

    Reproduction and observations

    • Launch Desktop and open an existing local conversation: the history spinner never finishes. Starting a new conversation also fails to produce a response.
    • Direct thread/read requests returned promptly, but the UI remained waiting for resume. Bundled-plugin reconciliation stalled on a child-process dependency.
    • The main process accumulated zombie bash, git, ps, and codex children. Shell-environment loading timed out after 5000 ms.
    • Binary inspection confirmed the handler jump at 0x117d9f78 targets the empty function at 0x11ce69c8, matching this issue.
    • An isolated Chromium user-data profile reproduced the spinner. Refreshing frontend evaluation-cache state did not resolve it; original state was restored before the successful test.

    Workaround and end-to-end verification
    A local preload guard preserving the existing SIGCHLD handler resolved the failure with the original installed executable and existing signed-in profile. The guard is restricted to the exact executable hash and verified handler offsets/bytes, is scoped to the desktop launcher, and removes LD_PRELOAD from the environment before children are launched.

    Verified results:

    1. Existing conversation history rendered; a thread/resume request completed in 177 ms, with no error.
    2. bundled_plugins_reconcile_completed appeared.
    3. A new GUI conversation successfully received the requested short diagnostic reply (the prompt explicitly requested no tools or operations).
    4. After restarting through the persistent normal launcher, the guard was loaded, plugin reconciliation completed, and the main process had zero zombie children at the follow-up check. No inspector/debugging ports remained open.

    No system package files, authentication data, or conversation history were deleted or modified by the workaround. Temporary diagnostic copies/profiles were removed. This is a version-specific local workaround, not an upstream fix or a long-duration stability claim.

    Please include Linux packaged-app smoke tests for opening existing local history and completing a new conversation, plus startup child-process completion. A bounded failure with a visible error for startup dependencies would also help avoid an indefinite spinner.

    Posted with the affected user's authorization; account/session identifiers, private paths, credentials, and conversation contents are omitted.

  22. lovasoa commented on Sep 28, 2026

    @lovasoa

    I suggest adding a test that launches the app and sends a prompt, and not releasing a new version of the app while that test fails.

  23. mcirsta commented on Sep 28, 2026

    @mcirsta

    I suggest adding a test that launches the app and sends a prompt, and not releasing a new version of the app while that test fails.

    I suggest someone actually testing the app for 5 minutes before releasing if that's not too much to ask.

  24. VirelNode commented on Sep 28, 2026

    @VirelNode

    I suggest adding a test that launches the app and sends a prompt, and not releasing a new version of the app while that test fails.

    I suggest someone actually testing the app for 5 minutes before releasing if that's not too much to ask.

    I was able to edit within a couple of minutes, but yea I agree.

  25. solankydev commented on Sep 28, 2026

    @solankydev

    Update: A new version arrived just a little while ago, and so far the issue seems to be fixed.

  26. yuzhu-oai commented on Sep 28, 2026

    @yuzhu-oai
    Contributor

    The issue has been fixed. Please update to the latest version.

  27. cylon58 commented on Oct 4, 2026

    @cylon58

    Additional confirmation from an Omarchy (Arch Linux) x86-64 installation, investigated on 2026-10-04. This concerns the already-affected build, not a claim that the upstream fix regressed.

    Distribution/version detail: the installed openai-codex-desktop package was 26.924.22138-1, and the locally configured pacman repository metadata still advertised that version at the time of investigation. The bundled app-server reported 0.158.0-alpha.2.1. Kernel: 7.2.5-3-omarchy, Wayland. We did not refresh repository metadata during this investigation, so we cannot establish the current state of the remote package mirror.

    Observed failure:

    • Local chats under Connections remained loading, although the local app-server successfully answered thread/read and thread/list requests.
    • A saved SSH connection failed. Direct SSH and Tailscale connectivity worked immediately outside Desktop.
    • Desktop's local ssh -G probe timed out after 5000 ms, followed by SSH: codex path probe timed out after 60000ms.
    • The desktop main process accumulated over 4,300 zombie helper children, including ssh, bash, git, ps, gh, and codex.
    • Restarting Desktop cleared the backlog but immediately reproduced new zombie helpers. Sending SIGCHLD did not recover it. SIGCHLD was caught and unblocked; we did not identify its native handler or independently prove the binary-level mechanism in this issue.

    Controlled version comparison on the same machine:

    Desktop version Isolated profile result
    26.924.22138 New zombie helpers and a 5000 ms shell-environment timeout
    Cached 26.915.31029 Zero zombie helpers; shell environment loaded in 395 ms

    Both tests used separate CODEX_HOME and user-data directories, with headless launches. Returning to 26.915.31029 with the existing real profile then restored both symptoms: the SSH codex-path probe completed in 675 ms, the remote app-server handshake succeeded, and the user confirmed local chat messages rendered again. No SSH/Tailscale configuration or conversation-history reset was required. No SIGCHLD preload patch was applied.

    The newer fixed build mentioned above has not been tested on this installation. This adds a version-controlled downgrade comparison and another affected distribution to the existing report. It also highlights that users with stale distribution package metadata can still encounter this after the upstream fix.

    Posted with the affected user's authorization. No raw logs, chat contents, credentials, private paths, hostnames, network addresses, or session identifiers are attached.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    LinuxappIssues related to the Codex desktop appbugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions