Skip to content

Codex desktop: send_message_to_thread fails with "'sendRequest.bind' is not a function" #51790

Open

Description

@jxfzzyz

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

26.1002.51308 (build 13417), read from the installed desktop application's Info.plist

What subscription do you have?

Not collected for this sanitized report

What platform is your computer?

macOS 26.4 (25E246), arm64

What issue are you seeing?

From a side conversation of an active local Codex task, all observed calls to mcp__codex_app__send_message_to_thread failed with:

'sendRequest.bind' is not a function.

Captured tool result:

{
  "isError": true,
  "texts": ["'sendRequest.bind' is not a function."]
}

list_threads and read_thread succeeded for the same local task. The target existed and was active. No successful delivery receipt was returned, and a subsequent thread read did not show the intended message.

This prevents a side-conversation assistant from delivering an explicitly authorized follow-up to the main task.

What steps can reproduce the bug?

  1. Open a side conversation of an existing active local Codex task.
  2. Explicitly authorize the assistant to send a short follow-up message to the main task.
  3. Call the exposed mcp__codex_app__send_message_to_thread tool with an existing task ID and a normal text prompt:
{
  "threadId": "<existing-main-thread-id>",
  "hostId": "local",
  "prompt": "Please review the consumer-coverage checklist when appropriate."
}
  1. Observe the tool error.
  2. Retry with hostId omitted or with a shorter prompt. The same error occurs.
  3. Read the target thread to check whether the follow-up was delivered; no intended message was observed.

Real session and thread IDs are omitted from this public report.

What is the expected behavior?

The follow-up should be delivered or queued in the specified existing task, and the tool should return an accurate success receipt.

Additional information

Observed on 2026-10-08. Installed codex-app-tools plugin cache version: 0.1.5.

The internal root cause is unknown; this report establishes the observed repeatable execution failure. No desktop restart, permission changes, plugin changes, project-code changes, or task-state changes were made to work around it.

This report excludes real thread IDs, project code, business data, credentials, and full conversation logs. A public issue search for repo:openai/codex "sendRequest.bind" returned no results before submission.

Activity

  1. added
    appIssues related to the Codex desktop app
    on Oct 7, 2026
  2. added
    bugSomething isn't working
    app-serverIssues involving app server protocol or interfaces
    tool-callsIssues related to tool calling
    on Oct 7, 2026
  3. kkc84719-byte commented on Oct 8, 2026

    @kkc84719-byte

    Additional report with update-regression evidence and a likely failing call site.

    Environment

    • ChatGPT/Codex desktop for macOS, Apple Silicon.
    • Installed version: 26.1002.52244, build 13536 (verified from the installed application's Info.plist).
    • macOS 26.2.
    • Observed on 2026-10-08.

    Observed behavior
    A development side chat can find/read the main local conversation, but sending an authorized follow-up to that conversation fails. The user's screenshot reports:

    sendRequest.bind is not a function
    

    Restarting the desktop client did not resolve the reported failure. Desktop logs separately confirm repeated send_message_to_thread calls returning success=false, while the target's thread/turns/list request succeeds immediately beforehand.

    Update comparison
    On this machine, logs from the previous client process (build 13232) contain successful send_message_to_thread calls. After updating to build 13536, the logs contain repeated failed calls through the same tool. This is observational regression evidence, not a controlled clean-install bisect.

    Read-only inspection of the installed client bundle
    In webview/assets/app-initial-61c077dcc1af.js, the side-chat parent-resolution function a4s:

    1. Obtains its client with fp(e, a).
    2. Successfully requests the first turn using t.listThreadTurns(...).
    3. Attempts to read the opening items with:
    RMe(t.sendRequest.bind(t), n, i.id, o, { timeoutMs: Z$e }, 2, "asc")

    The imported fp resolves to jI in app-shared-6c00c2afcf84.js, which returns a host RPC proxy (i.forHost(t) or client.rpc). The item-reading helper resolves to Xz, which expects a callable request function and invokes thread/items/list.

    The reported error and the successful first-turn request followed by immediate send failure are consistent with .bind being unavailable on that RPC proxy's sendRequest member. Please check whether this path retained a legacy client-method assumption after the RPC migration, and use the supported RPC item/history-reading interface. This diagnosis is an inference from the shipped bundle and logs; no patched client was run.

    Expected behavior
    A side chat should deliver or queue the authorized follow-up in its main conversation and return an accurate delivery receipt.

    Application signature verification passes. No client package, permission settings, or project code was modified during this investigation. Real conversation IDs, local usernames/paths, business content, full logs, and the original screenshot are omitted from this public comment.

  4. maxitaaaa commented on Oct 8, 2026

    @maxitaaaa

    I am also seeing this failure on Windows when a side chat tries to send an authorized status report to its main chat.

    Environment:

    • Codex Desktop Windows package 26.1002.7124.0, verified from the installed package.
    • Windows 11 Home 25H2, build 26200.9457.
    • Observed on October 8, 2026.

    The task list could be read successfully, but both attempts to send a message to the main chat failed with the same reported error: the implementation tried to use sendRequest.bind(), but sendRequest was not a callable function. This matches the non-function error tracked in this issue.

    Read-only inspection of the desktop logs independently found two send_message_to_thread calls with success=false, at 08:39:01.315 UTC and 08:39:36.001 UTC. The exact exception wording above comes from the side chat's report; those desktop log entries confirm the failed calls but do not include the exception text.

    The spreadsheet update and website update had already completed successfully. Only delivery of the completion report to the main chat was blocked. This distinction matters: the reporting failure should not cause the completed work to be repeated.

    Expected behavior: the side chat should deliver or queue the report in the existing main chat and return an accurate delivery receipt.

    I have not established why sendRequest has the wrong type, or whether an app update caused it. I did not issue additional test messages during this read-only check. Please include the Windows side-chat-to-main-chat path when investigating this issue.

    This comment excludes private messages, real thread IDs, project names and paths, workbook contents, credentials, screenshots, and full logs. No UI automation or changes to the app package, task state, or queue were made for this report.

  5. GGQJavakf commented on Oct 9, 2026

    @GGQJavakf

    Additional Windows reproduction, observed on 2026-10-09 (UTC+8).

    Environment

    • Windows x64.
    • Installed Codex Desktop Windows package: 26.1002.7124.0 (verified from the installed package path).
    • Bundled codex-app-tools plugin cache version: 0.1.5.

    Observed behavior

    From a side conversation, the user explicitly authorized sending follow-up instructions to existing local Codex tasks. Calls to mcp__codex_app__send_message_to_thread failed across five destinations with the same error:

    'sendRequest.bind' is not a function.
    

    No successful delivery receipt was returned, and reading the destination threads did not show the intended new prompts. read_thread and wait_threads worked.

    The error persisted when:

    • Providing hostId: "local".
    • Omitting hostId.
    • Opening the destination task in the desktop app before retrying.
    • Explicitly specifying one destination's existing model and reasoning settings.

    Reproduction

    1. Open a side conversation of an existing local Codex task.
    2. Authorize sending a follow-up to an existing local task.
    3. Call send_message_to_thread with its task ID and a normal text prompt.
    4. Observe the JavaScript error and read the destination to check delivery.

    Read-only investigation

    In the installed Windows bundle, webview/assets/app-initial-25361a10f2bf.js, the cross-thread send path resolves the side conversation's parent. Its a4s helper falls back to reading the parent's opening turn/items and calls:

    RMe(t.sendRequest.bind(t), n, i.id, o, { timeoutMs: Z$e }, 2, "asc")

    The imported accessor fp resolves through lXt to jI in app-shared-40678a67f0e3.js. This accessor returns a host RPC interface/proxy, including paths returning i.forHost(t) or client.rpc.

    This is consistent with the RPC-interface mismatch discussed above. It is a source-based diagnostic inference, not a confirmed runtime stack trace or a version bisect.

    Workaround and expected behavior

    The bundled official CLI's codex exec resume <original-thread-id> - --json, run in each task's original working directory with the prompt on stdin, successfully continued the same existing sessions. Desktop thread reads confirmed the new prompts. Already-running tasks were allowed to finish before CLI resumption to avoid simultaneous execution.

    The native desktop sending failure remains unresolved. Valid messages should be delivered/queued with an accurate receipt; unavailable destinations should produce an actionable policy/state error rather than this internal JavaScript exception.

    No desktop package, credentials, permissions, or global configuration were modified. This public report excludes real thread IDs, private prompts, repository details, credentials, and full session logs.

  6. aidawilliam41-ops commented on Oct 9, 2026

    @aidawilliam41-ops

    Further Windows diagnostics, adding RPC property-resolution evidence to the call-site analyses above.

    Environment: Observed 2026-10-09 UTC on Windows; running AppX package OpenAI.Codex_26.1002.7124.0_x64__2p2nqsd0c76g0. This identifies the package, not every internal component version.

    Observed: Three send_message_to_thread calls returned isError: true with 'sendRequest.bind' is not a function. Both hostId: "local" and omission failed. Desktop logs independently show renderer-handler execution, successful thread/turns/list, then success=false after 28 ms, 28 ms, and 160 ms. Those log entries contain no exception stack.

    Additional static evidence: In app-shared-40678a67f0e3.js:

    • DFt.get extends an RPC path when a string property is accessed.
    • uFt permits only own properties when traversing a function (Object.hasOwn), excluding inherited Function.prototype.bind.
    • OFt.call rejects a non-callable resolved value using the exact error template '<path>' is not a function.

    On this proxy path, the previously identified t.sendRequest.bind(t) call in app-initial-25361a10f2bf.js would invoke the remote path sendRequest.bind, explaining the precise error. The expected RPC target also defines sendRequest, and another bundled call uses jI(...).sendRequest('thread/items/list', ...) directly.

    The live target selected by jI, its value/type, and the exception stack were not captured; this remains a static explanation consistent with the failure. Earlier delivery remains unconfirmed.

    A source correction should avoid .bind on the RPC stub and use its supported item-reading interface. A forwarding function is an untested candidate. Verification should require tool success and exactly one matching harmless message in the destination.

    Bundle identity: app.asar SHA-256 76FE7078248C00E4E03DD2177A4275EC9CE158A9DD43452A4F0427D39A4ED012.

  7. sysoft commented on Oct 9, 2026

    @sysoft

    I'm also encountering this on macOS with Codex 26.1007.21159 (build 20052, production channel). The app updater reports no available update.

    From a side conversation, list_threads successfully found the active main thread, but send_message_to_thread failed twice—both with hostId: "local" and with hostId omitted—with:

    'sendRequest.bind' is not a function.
    

    Both calls returned isError: true, with no successful delivery confirmation. Observed on October 9, 2026.

  8. rasokiwayami commented on Oct 9, 2026

    @rasokiwayami

    Adding an executable regression and a forwarding-callback candidate to the
    call-site and RPC-path analyses above.

    Environment and observed failure

    • macOS 26.6.2 (25G83), desktop version 26.1007.21159, build 20052.
    • Two authorized side-to-parent sends failed with
      'sendRequest.bind' is not a function. on October 9, 2026.
    • Bounded desktop-log inspection shows thread/turns/list succeeding immediately
      before each failed send; elapsed time from renderer execution start to failure
      was 5 ms and 4 ms. Those log records do not contain an exception stack.
    • Restarting had not resolved the problem. No installed app files were modified.

    Source-level candidate

    In this build, Moc in app-initial-c468e3fd7f91.js passes
    r.sendRequest.bind(r) to the opening-item pagination helper. When r is the
    host RPC stub, .bind extends the remote property path instead of binding a
    local JavaScript method. The shared bundle's pPt function permits only own
    properties while traversing a function, so inherited Function.prototype.bind
    does not resolve. Its caller rejects the non-callable sendRequest.bind path.

    The narrow candidate is a normal forwarding callback at this call site:

    - await xHe(r.sendRequest.bind(r), n, a.id, o, { timeoutMs: kle }, 2, `asc`)
    + await xHe((...args) => r.sendRequest(...args), n, a.id, o, { timeoutMs: kle }, 2, `asc`)

    The production source should use the request callback's existing type/contextual
    typing. These are minified symbols identifying the shipped call site, not a
    patch against a file in the public repository. This candidate leaves RPC
    property-access restrictions and message-authorization checks unchanged.

    Verification performed

    • Portable Node regression: the legacy adapter failed 2 of 4 tests with the
      reported RPC-path error; the forwarding adapter passed all 4.
    • Six further local tests evaluated the installed Moc, item-page helper VV,
      and property resolver pPt functions in isolation. The unmodified call site
      reproduces the exact error. Replacing only its callback expression passes
      checks for compaction skipping and pagination, request parameters/timeouts,
      rejection propagation without retry, repeated-cursor rejection, empty parent
      history, and the cached opening-context path.
    • Final local run: 10 tests passed, 0 failed, Node.js 26.3.1. RPC dispatch and
      transport were modeled in process; all IDs, data and messages were synthetic.

    This supports the narrow callback correction, but it is not an end-to-end
    desktop fix verification
    . A patched app was not run, and the original live
    exception stack was not captured. Maintainers should still verify that the
    authorized side-to-parent send yields one matching message and an accurate
    delivery receipt, including the paginated-history fallback.

    For identifying the tested build, the local checks required these asset hashes:

    app-initial-c468e3fd7f91.js
    SHA-256 efd785d44bc6f07771f3d5a21cf255112d0f17969b398889e6a8a4868338152f
    app-shared-2f2228189a8d.js
    SHA-256 47b7173d0bbecc5f6f32157134add7be65c0a22c2555c5bbeb9665b1bcded7b0
    

    The portable regression below is original test code, not a copy of the app
    implementation. It models the relevant RPC property-path behavior and requires
    no app installation or account. Inspection and test preparation were assisted
    by Codex. No conversation IDs, private prompts, local user paths, credentials,
    or full logs are included.

    Portable regression: save as regression.test.mjs and run node --test regression.test.mjs
    import assert from 'node:assert/strict';
    import test from 'node:test';
    // Standalone source-level candidate; this does not patch the installed app.
    function forwardSendRequest(client) {
      return (...args) => client.sendRequest(...args);
    }
    
    // A small in-process model of the observed RPC property-path behavior.
    // It intentionally does not implement the application's wire protocol.
    function rpcClient(sendRequest, paths, path = []) {
      return new Proxy(function () {}, {
        get(_target, key) {
          return rpcClient(sendRequest, paths, [...path, key]);
        },
        apply(_target, _receiver, args) {
          paths.push(path.join('.'));
          if (path.join('.') !== 'sendRequest') {
            throw new TypeError(`'${path.join('.')}' is not a function.`);
          }
          return sendRequest(...args);
        },
      });
    }
    
    test('the legacy binding reproduces the reported RPC-path error', () => {
      const paths = [];
      const client = rpcClient(() => assert.fail('request must not run'), paths);
      assert.throws(() => client.sendRequest.bind(client), {
        name: 'TypeError', message: "'sendRequest.bind' is not a function.",
      });
      assert.deepEqual(paths, ['sendRequest.bind']);
    });
    
    test('adapter is lazy and forwards method, parameters, options and result', async () => {
      const paths = [];
      const params = { threadId: 'fixture-parent', turnId: 'fixture-turn',
        cursor: null, limit: 2, sortDirection: 'asc' };
      const options = { timeoutMs: 10000 };
      const result = { data: [], nextCursor: null };
      const client = rpcClient((...args) => {
        assert.deepEqual(args, ['thread/items/list', params, options]);
        return Promise.resolve(result);
      }, paths);
      const sendRequest = forwardSendRequest(client);
      assert.deepEqual(paths, []);
      assert.equal(await sendRequest('thread/items/list', params, options), result);
      assert.deepEqual(paths, ['sendRequest']);
    });
    
    test('adapter preserves a native method receiver', async () => {
      const client = {
        marker: 'native-client',
        sendRequest(...args) { assert.equal(this, client); return [this.marker, args]; },
      };
      assert.deepEqual(await forwardSendRequest(client)('method', {}, {}),
        ['native-client', ['method', {}, {}]]);
    });
    
    test('adapter propagates a request rejection without retrying', async () => {
      const paths = [];
      const failure = new Error('fixture transport failure');
      const client = rpcClient(() => Promise.reject(failure), paths);
      await assert.rejects(async () => forwardSendRequest(client)('method', {}),
        error => error === failure);
      assert.deepEqual(paths, ['sendRequest']);
    });
  9. rasokiwayami commented on Oct 9, 2026

    @rasokiwayami

    Verified local workaround: codex queue using the bundled CLI.

    Following up on my earlier regression analysis: on October 9, 2026, I delivered
    a harmless test message to the same existing parent conversation through the
    CLI while leaving the desktop app unmodified.

    Tested environment: macOS 26.6.2, desktop 26.1007.21159 / build 20052,
    bundled CLI 0.162.0-alpha.17.2. On this installation the command was:

    /Applications/ChatGPT.app/Contents/Resources/codex-cli/bin/codex queue \
      --thread '<exact-existing-parent-thread-id>' \
      --message '<authorized-follow-up-message>'

    Use the CLI bundled with the app; its installation path may differ.

    Verification went beyond the command's success response:

    1. The command returned a queued-message ID for the intended parent.
    2. Read-only inspection confirmed that exact queue item contained the intended
      destination and complete test text. The parent was still processing its
      existing work at that point.
    3. A subsequent desktop thread read showed the test text as a userMessage in
      the parent's conversation, and the corresponding queue item was gone.

    This confirms delivery to the parent history for the tested message. It does
    not establish that the parent performed any requested work, and it does not fix
    the original desktop send_message_to_thread call path. This is queued delivery,
    not a guarantee of immediate steering.

    I used the ordinary command without --remote. An earlier explicit
    --remote unix:// attempt failed before sending because this installation had
    no default shared-server control socket; the ordinary command then succeeded.
    I did not run exec resume, interrupt the parent, patch or re-sign the app,
    restart it, change configuration/permissions, or write directly to its database
    for this workaround. Only the CLI's normal queue operation wrote the message.

    This is one verified macOS case; Windows and other versions remain untested by
    me. Real conversation IDs and private message contents are omitted.

  10. chenzilin100 commented on Oct 10, 2026

    @chenzilin100

    Still reproducible on Windows x64, Codex Desktop 26.1007.2314.0, observed on October 10, 2026 (UTC+8). Adding a comparison between side-conversation and ordinary cross-thread sends in the same running Desktop process.

    • Side conversation → active main conversation: three sends failed with the reported sendRequest.bind is not a function error. Desktop logs show send_message_to_thread renderer execution followed by success=false after 43 ms, 48 ms, and 21 ms. The target's thread/turns/list request succeeded immediately before each failure. The exact error wording was reported by the user from the side conversation; these log entries contain no exception stack.
    • Ordinary main conversation → another ordinary local conversation: an explicitly authorized test using the same exposed mcp__codex_app__send_message_to_thread tool succeeded. The destination was idle. No model or reasoning override was supplied. The tool returned the intended destination ID, the destination replied with the unique test marker, a subsequent read_thread returned that reply, and the same Desktop process logged success=true.

    A read-only check of this Windows bundle found the corresponding call site in webview/assets/app-initial-b8e1c8014bb4.js. In the minified joc function, the call to Moc is conditional on the source's opening context having sideConversation === true, together with parent and host checks. Ordinary source conversations skip that branch. In Moc, the opening-history fallback still passes r.sendRequest.bind(r) to xHe.

    The successful ordinary send and the conditional call site support narrowing this reproduction to the side-conversation path. The RPC proxy internals and a live exception stack were not independently captured in this Windows check. No client patch, restart, configuration change, or direct database edit was used.

  11. upeartaker commented on Oct 10, 2026

    @upeartaker

    Additional reproduction and read-only RPC diagnosis on macOS.

    Environment

    • Desktop: 26.1007.21159, build 20052, verified from the installed application Info.plist.
    • macOS 27.0.1, Apple Silicon arm64.
    • Bundled codex-app-tools cache version: 0.1.6.
    • Observed October 10, 2026.

    Observed behavior
    From a side conversation, explicitly authorized send_message_to_thread calls to the existing active parent failed with the exact tool result:

    'sendRequest.bind' is not a function.
    

    The same side conversation could read the parent using read_thread. Ordinary conversations were successfully sending messages in the same running desktop process. Four failed send responses were found in this session's desktop logs; the parent thread/turns/list request succeeded immediately before each failure. For example, the relevant sanitized fields from one attempt were:

    2026-10-10T09:42:57.142Z dynamic_app_tool_renderer_execution_started tool=send_message_to_thread
    2026-10-10T09:42:57.145Z response_routed method=thread/turns/list errorCode=null
    2026-10-10T09:42:57.146Z Sending server response success=false tool=send_message_to_thread
    

    Additional code-level evidence
    Read-only inspection of this installed bundle found:

    • In webview/assets/app-initial-c468e3fd7f91.js, joc conditionally enters the parent-resolution path for sideConversation === true. The Moc opening-history fallback calls xHe(r.sendRequest.bind(r), ...) after listThreadTurns.
    • The accessor behind r resolves to QL in app-shared-2f2228189a8d.js, returning a host RPC proxy (forHost(...) / client.rpc). The exposed facade does have a sendRequest getter.
    • The RPC proxy's property handler appends string property names to the remote path, so accessing .sendRequest.bind constructs the remote path ["sendRequest", "bind"].
    • The RPC resolver pPt permits only own properties when traversing a function. Function.prototype.bind is inherited, so it resolves to undefined. APt.call then emits the exact error template '<path>' is not a function., which matches the observed message.

    This provides a specific explanation for the error wording beyond the suspected call site: .bind is being resolved over RPC instead of applied as a local function operation. A local forwarding callback such as (...args) => r.sendRequest(...args) appears to be the appropriate direction for a fix, subject to maintainers' type/lifetime checks and regression tests for side conversations with paginated/unloaded opening history.

    The diagnosis is based on observed tool failures, desktop logs, and static inspection of the installed bundle; no live exception stack was captured and no patch was applied or validated. The app was not restarted, re-signed, or modified, and no direct database edits were made. Real thread IDs, usernames, project paths, credentials, and conversation contents are omitted.

  12. sysoft commented on Oct 10, 2026

    @sysoft

    macOS candidate hotfix: minimal copy-and-patch script

    Building on the RPC-path analysis and forwarding-callback proposal above, I prepared a small macOS patch script and verified that it produces an internally consistent, ad-hoc-signed application copy.

    This is an experimental local hotfix, not a confirmed end-to-end fix or an official release. The patched app has not been launched, and real side-conversation message delivery through it has not been verified.

    The one-call-site change is:

    -xHe(r.sendRequest.bind(r),n,a.id,o,{timeoutMs:kle},2,`asc`)
    +xHe((...args)=>r.sendRequest(...args),n,a.id,o,{timeoutMs:kle},2,`asc`)

    This avoids resolving sendRequest.bind as a remote RPC property path. The local callback forwards the arguments through r.sendRequest(...args), retaining its receiver. It does not change destination checks, authorization rules, or the downstream send operation.

    Verified locally: macOS desktop 26.1007.21159 / build 20052.

    • 16 isolated tests passed using extracted shipped functions with bounded transport/parser stubs: exact original error reproduction, forwarding, pagination/cursors, cached/empty opening history, error propagation, ordinary sends, and the existing ancestor restriction. These are not live IPC or delivery tests.
    • The script below generated an actual application copy. Independent verification checked that the original ASAR body remained byte-for-byte intact, the redirected JavaScript member matched the intended patch, and the updated header matched ElectronAsarIntegrity.
    • codesign --verify --deep --strict passed for the generated copy and the untouched original.
    • Existing-output refusal, repeated-patch refusal, and refusal to write inside the source app were checked.

    Usage

    Requires Python 3, macOS ditto, and codesign. Save the script as patch_macos.py, then run:

    python3 patch_macos.py /Applications/ChatGPT.app
    # Optional explicit source/output:
    python3 patch_macos.py /Applications/Codex.app "$HOME/Applications/Codex-Fixed.app"

    The default output is ~/Applications/ChatGPT-Sidechat-Fix.app. It preserves the original app and does not change user data, launch either app, or send a message. Quit the original before testing the copy; do not run both against the same profile simultaneously. Return to the original to roll back.

    There is no version or file-hash allowlist. It searches embedded JavaScript for the exact faulty call above and only patches a unique match. This does not make it universal: builds with renamed minified symbols or different packaging will stop without patching. The script recalculates SHA-256 ASAR integrity metadata because Electron needs it; those hashes are not compatibility fingerprints. Avoid running it while the source app is being updated.

    Signing caveat: modifying the app invalidates its original signature, so the copy is locally ad-hoc signed. It is no longer OpenAI-signed/notarized; launch, Keychain access, sign-in, system permissions, or updates may be affected. Passing codesign verification does not establish runtime compatibility. The script does not disable Gatekeeper or Electron integrity enforcement. Windows/Linux are not implemented or tested by this script.

    Complete 86-line macOS script (Python standard library only; messages are in Chinese)
    #!/usr/bin/env python3
    """macOS: python3 patch_macos.py /Applications/ChatGPT.app [输出.app]"""
    import hashlib, json, os, plistlib, shutil, struct, subprocess, sys, tempfile
    from pathlib import Path
    
    BEFORE = b'xHe(r.sendRequest.bind(r),n,a.id,o,{timeoutMs:kle},2,`asc`)'
    AFTER = b'xHe((...args)=>r.sendRequest(...args),n,a.id,o,{timeoutMs:kle},2,`asc`)'
    sha = lambda data: hashlib.sha256(data).hexdigest()
    
    
    def require(ok, message):
        if not ok:
            raise RuntimeError(message)
    
    
    def run(*args):
        p = subprocess.run(list(map(str, args)), capture_output=True, text=True)
        require(p.returncode == 0, p.stderr or p.stdout)
    
    
    def files(node):
        for name, child in node.get('files', {}).items():
            if 'files' in child:
                yield from files(child)
            elif name.endswith('.js') and 'offset' in child and not child.get('unpacked'):
                yield child
    
    
    def main():
        require(sys.platform == 'darwin', '仅支持 macOS')
        require(2 <= len(sys.argv) <= 3, __doc__)
        app = Path(sys.argv[1]).expanduser().resolve(strict=True)
        output = Path(sys.argv[2] if len(sys.argv) == 3 else '~/Applications/ChatGPT-Sidechat-Fix.app').expanduser().absolute()
        require(not output.exists() and not output.is_symlink() and output.suffix == '.app'
                and output.resolve() != app and app not in output.resolve().parents, '输出已存在或路径无效;不会覆盖')
        source = app / 'Contents/Resources/app.asar'
        plist = plistlib.loads((app / 'Contents/Info.plist').read_bytes())
        require(plist.get('CFBundleIdentifier') == 'com.openai.codex', '请选择 Codex 应用')
        with source.open('rb') as f:
            a, b, c, n = struct.unpack('<4I', f.read(16))
            require(a == 4 and b == c + 4 and c == 4 + (n + 3) // 4 * 4
                    and 0 < n < 64 * 1024 * 1024 and b + 8 <= source.stat().st_size, 'ASAR 格式不支持')
            header, base = json.loads(f.read(n)), b + 8
            matches = []
            for node in files(header):
                f.seek(base + int(node['offset']))
                data = f.read(node['size'])
                if BEFORE in data:
                    matches.append((node, data))
        require(len(matches) == 1 and matches[0][1].count(BEFORE) == 1,
                '未唯一找到目标错误调用:可能已修复,或新版本的代码结构不同。未修改任何应用')
        node, data = matches[0]
        patched = data.replace(BEFORE, AFTER)
        body_size = source.stat().st_size - base
        block = node.get('integrity', {}).get('blockSize', 4194304)
        require(isinstance(block, int) and block > 0, '无效 ASAR blockSize')
        node.update(size=len(patched), offset=str(body_size), integrity={'algorithm': 'SHA256', 'hash': sha(patched),
                    'blockSize': block, 'blocks': [sha(patched[i:i + block]) for i in range(0, len(patched), block)]})
        raw = json.dumps(header, ensure_ascii=False, separators=(',', ':')).encode()
        pad = (-len(raw)) % 4
        prefix = struct.pack('<4I', 4, len(raw) + pad + 8, len(raw) + pad + 4, len(raw)) + raw + b'\0' * pad
        output.parent.mkdir(parents=True, exist_ok=True)
        with tempfile.TemporaryDirectory(prefix='.codex-hotfix-', dir=output.parent) as tmp:
            staged = Path(tmp) / output.name
            print('已找到错误调用,正在制作本地签名副本……', flush=True)
            run('/usr/bin/ditto', app, staged)
            target = staged / 'Contents/Resources/app.asar'
            with source.open('rb') as src, target.open('wb') as dst:
                dst.write(prefix)
                src.seek(base)
                shutil.copyfileobj(src, dst, 1048576)
                dst.write(patched)
            plist.setdefault('ElectronAsarIntegrity', {})['Resources/app.asar'] = {'algorithm': 'SHA256', 'hash': sha(raw)}
            (staged / 'Contents/Info.plist').write_bytes(plistlib.dumps(plist, sort_keys=False))
            run('/usr/bin/codesign', '--force', '--sign', '-', '--preserve-metadata=entitlements,flags,runtime', staged)
            run('/usr/bin/codesign', '--verify', '--deep', '--strict', staged)
            require(not output.exists() and not output.is_symlink(), '输出被占用;停止')
            os.rename(staged, output)
        print(f'完成:{output}\n原版保留。退出原版后再打开副本,不要同时运行。\n副本为本地签名,登录/钥匙串/系统授权可能受影响;真实消息投递尚未验证。')
    
    
    if __name__ == '__main__':
        try:
            main()
        except Exception as exc:
            sys.exit(f'停止:{exc}')

    The existing bundled CLI queue workaround remains an alternative for keeping the official app unmodified. For the actual product fix, the local forwarding callback should be integrated and tested in the desktop source rather than relying on users patching packaged bundles.

  13. cxc20251020-oss commented on Oct 10, 2026

    @cxc20251020-oss

    Additional Windows verification on 2026-10-11 (UTC+8), building on the forwarding-callback candidate already discussed above.

    Environment

    • Windows x64, installed/running Codex Desktop package 26.1007.2314.0.
    • Bundled codex-app-tools cache 0.1.6.
    • The native side-conversation send failed with 'sendRequest.bind' is not a function.; the destination read did not contain the intended message.

    Offline candidate and checks

    The installed webview/assets/app-initial-b8e1c8014bb4.js contains one sendRequest.bind occurrence, in Moc. An offline copy changes only this callback:

    - xHe(r.sendRequest.bind(r),n,a.id,o,{timeoutMs:kle},2,`asc`)
    + xHe((...args)=>r.sendRequest(...args),n,a.id,o,{timeoutMs:kle},2,`asc`)

    The installed Moc, item-page helper nB, and RPC property resolver aFt were extracted and evaluated in isolation. Transport, scope and opening-context parsing were synthetic test doubles; no live messages or credentials were used in these tests.

    14 local tests passed, 0 failed, including:

    • Reproducing the exact remote-bind error with the original function, before any item request.
    • Resolving the synthetic parent after the callback change, preserving request arguments, page size and timeout.
    • Compaction skipping, pagination, cached and nonpaginated opening contexts, and empty history.
    • Generic rejection propagation without retry; preserving the existing bounded oversized-page handling.
    • Rejecting unchanged/cyclic cursors and unexpected turn IDs.
    • Preserving a normal method receiver and returning null when the source marker is absent.
    • Verifying that the candidate changes exactly one expression and leaves every other byte intact, including the dispatch/native-ancestry guard.

    The complete candidate asset also passed node --check. Installed assets were re-read afterward and remained unchanged.

    Source SHA-256:

    • app-initial-b8e1c8014bb4.js: 799331dde54905c4df5e360f23a9621141759e2c0acb230aeab909f9904b646f
    • app-shared-737655e1fb23.js: a1daa891e89a395b8db399ff6eaa365f12a86880c3d8cf891caf4ccbcb9eebf5

    This is not a patched-desktop end-to-end result. The Windows-protected installed package was not modified; no permissions were changed and the client was not restarted. A live exception stack was not captured. Maintainers still need to verify native side-to-parent delivery and its receipt in a patched build.

    Separately, the CLI queue workaround is now verified on this Windows installation. The app's CLI 0.162.0-alpha.17.2 accepted one harmless message for the existing idle parent using codex queue --thread ... --message .... Desktop read_thread then showed the exact test text as a user message and the parent's matching acknowledgment; the turn completed. This used neither --remote nor exec resume, and does not repair the native tool. Real IDs and private message contents are omitted.

  14. 80533 commented on Oct 11, 2026

    @80533

    Additional macOS reproduction observed on October 11, 2026.

    Environment (verified from the installed app and local plugin cache):

    • Desktop: 26.1007.21159, build 20052.
    • Platform: macOS, Apple Silicon (arm64).
    • codex-app-tools cache version: 0.1.6.

    From a side conversation, the user explicitly authorized sending a completion handover to its existing local main conversation. Two calls to mcp__codex_app__send_message_to_thread failed with the exact tool result:

    'sendRequest.bind' is not a function.
    

    Both returned isError: true. Supplying hostId: "local" and omitting hostId produced the same error. The main conversation could be listed/read successfully. No successful delivery receipt was returned, so this report does not claim that the handover was delivered.

    Read-only desktop-log inspection confirms that each failed send immediately followed a successful thread/turns/list response. Sanitized example:

    2026-10-11T13:09:05.199Z renderer_execution_started tool=send_message_to_thread
    2026-10-11T13:09:05.206Z response_routed method=thread/turns/list errorCode=null durationMs=5
    2026-10-11T13:09:05.208Z Sending server response tool=send_message_to_thread success=false
    

    A second attempt shows the same sequence. The exact exception comes from the tool response; these log records contain no exception stack.

    The user reports that a previous desktop restart did not resolve the problem. No restart, patched app, permission/configuration change, or additional test message was performed for this report.

    Expected: deliver or queue the explicitly authorized side-to-main message and return an accurate receipt, instead of an internal JavaScript exception.

    This report was prepared with Codex assistance and posted at the user's request. Real thread IDs, business content, local paths/usernames, credentials, screenshots, and full logs are omitted.

  15. drewmad commented on Oct 12, 2026

    @drewmad

    Also seeing this on macOS.

    • ChatGPT/Codex app 26.1007.30912 (build 20156); bundled codex-cli 0.162.0-alpha.17.2
    • Side chat → main chat: send_message_to_thread fails with "'sendRequest.bind' is not a function" and the message isn't delivered. list_threads, read_thread and wait_threads work.
    • Seen Oct 11, 2026, at 7:18 PM, 8:00 PM and 8:32 PM ET; persists after restart.
    • Workaround: send from the main chat directly.
  16. maxitaaaa commented on Oct 14, 2026

    @maxitaaaa

    I retested this on Windows on October 14, 2026, after updating to installed Codex Desktop package 26.1007.9446.0 (verified from Windows package metadata, not the About dialog). The side-chat-to-main-chat failure is still reproducible.

    Side chat -> its main chat

    • I explicitly authorized a harmless message that only requested a receipt.
    • The side chat reported isError: true with the same exact error:
      'sendRequest.bind' is not a function.
      
    • The result shown at approximately 13:52 UTC+08:00 stated that no new confirmation appeared in the main chat.
    • This result is documented by the side chat's displayed test report. I did not capture a live exception stack or perform a new version bisect.

    Ordinary chat -> another ordinary chat, tested shortly beforehand

    • The same send_message_to_thread tool returned success for a separate, unarchived local conversation.
    • Read-only inspection of the destination's persisted session confirmed that the complete unique test message arrived at 13:48:06 UTC+08:00, including the correct source-chat reference and input text.
    • The destination was processing its original task. No acknowledgment had been observed when this check finished, so this establishes incoming-message delivery, not completion of the destination's work.
    • An initial attempt to an older archived conversation was rejected as archived. That expected state rejection is separate from the side-chat exception.

    A read-only inspection of the current installed bundle also found one sendRequest.bind occurrence in webview/assets/app-initial-102e45562729.js. This static observation is consistent with the reported failure; it is not a claim that a candidate patch has been validated.

    Please verify the side-conversation parent-resolution path, including its opening-history fallback, in a supported Windows release. A successful ordinary cross-chat send does not verify that path. Please provide a fix version or a supported workaround.

    The communication test did not modify business files or patch the installed application. This comment contains no real conversation IDs, private prompts, project paths, credentials, raw logs, or screenshots. The original screenshot was omitted because it includes non-English UI text.

  17. eric-1219 commented on Oct 14, 2026

    @eric-1219

    Additional Windows reproduction and isolated candidate-fix verification on 2026-10-15 (UTC+08:00).

    Environment

    • Codex App updater metadata: 26.1007.71326, build 20398, prod; up_to_date during diagnosis.
    • Installed Windows MSIX package: 26.1007.9446.0 (a separate version field).
    • Bundled codex-app-tools: 0.1.6.

    Observed behavior
    An explicitly authorized side-conversation message to its existing active local parent fails with:

    'sendRequest.bind' is not a function.
    

    The tool returns isError: true. Both supplying hostId: "local" and omitting it failed. Reading the main thread works. No successful delivery receipt was returned. This is a side-to-parent failure, not a claim that all cross-thread messaging fails.

    Read-only local logs show thread/turns/list succeeding immediately before the send tool reports failure at 2026-10-14 16:16:16 UTC and 16:16:43 UTC. The exact exception is from the tool result; those log entries do not provide a live exception stack.

    Installed-code observation
    In webview/assets/app-initial-102e45562729.js, the side-conversation path uses Noc to load the parent's opening context. With an unloaded openingTurn, it calls:

    CHe(r.sendRequest.bind(r), n, a.id, o, {timeoutMs: Ole}, 2, `asc`)

    The imported client getter resolves to KI in the shared asset and returns an RPC proxy. The observed failure is consistent with resolving sendRequest.bind as an unsupported RPC path rather than local Function.bind.

    This independently supports the forwarding-callback candidate discussed above:

    - CHe(r.sendRequest.bind(r), n, a.id, o, {timeoutMs: Ole}, 2, `asc`)
    + CHe((...args) => r.sendRequest(...args), n, a.id, o, {timeoutMs: Ole}, 2, `asc`)

    Isolated verification
    The installed Noc and actual item-page helper nB were extracted read-only and executed with an isolated RPC mock; transport/scope/opening-context fixtures were synthetic.

    • Original callback: reproduces the exact error.
    • Candidate: passes 10 regression categories: RPC dispatch, destination/timeout preservation, cached opening, empty history, legacy hydration, pagination/wrapped items, cursor guard, access-denial propagation, no-origin result, and wrong-turn rejection.
    • Exactly one callback expression is replaced; subsequent native relationship/authorization checks are not removed.
    • Source asset SHA-256: c59b2a0be6c13496b30ebda167925cdccab26799cae350c62d2b37afe3589b57.

    Limits: This is not patched-app end-to-end verification. No installed application files, permissions, main-task state, or project files were modified, and the app was not restarted. Please validate native side-to-parent delivery and its success receipt in a supported fix build.

    Prepared with Codex assistance and posted at the user's request. Email, real thread IDs, private prompts, credentials, full logs, and personal local paths are excluded.

  18. youngandboor commented on Oct 15, 2026

    @youngandboor

    Additional macOS reproduction on 2026-10-15, with read-only inspection of the installed desktop bundle.

    Environment

    • Desktop version: 26.1007.30912, build 20156 (verified from installed Info.plist).
    • Build commit recorded in desktop logs: a993bdbe5bb9503cb84de1e67d5635cf186a959f.
    • Local side conversation sending an explicitly authorized follow-up to its existing main conversation.

    Observed behavior

    The main conversation was discoverable through list_threads. Calling send_message_to_thread with its ID, hostId: "local", and an ordinary text prompt returned isError: true:

    'sendRequest.bind' is not a function.
    

    Sanitized desktop-log sequence:

    2026-10-15T02:36:51.240Z dynamic_app_tool_renderer_execution_started tool=send_message_to_thread
    2026-10-15T02:36:51.262Z response_routed method=thread/turns/list errorCode=null durationMs=8
    2026-10-15T02:36:51.264Z Sending server response tool=send_message_to_thread success=false
    

    No successful delivery receipt was returned. The exception text comes from the tool result; these desktop log entries do not contain an exception stack.

    Installed-code observation

    In webview/assets/app-initial-6350d04672d0.js, the side-conversation routing function joc calls Moc to resolve the parent's opening context. When openingTurn is null, Moc fetches the first turn, then invokes:

    xHe(r.sendRequest.bind(r), n, a.id, o, {timeoutMs: kle}, 2, `asc`)

    The client getter jg resolves through the shared export to KI, which returns a host RPC proxy (forHost(...) or client.rpc). This is consistent with attempting to resolve .bind through the RPC proxy instead of binding a local JavaScript function. The problematic call precedes the message dispatch step.

    Please validate the supported RPC history-reading interface or a normal forwarding callback, and add a regression covering side-to-parent delivery when the parent's opening history is not already loaded. No patched-client verification was performed here.

    Earlier success and limits

    Logs from this machine show a successful send_message_to_thread call on 2026-10-08 under build 11645. That earlier call's conversation relationship and history state were not established, so this is NOT a version bisect and does not prove which update introduced the bug. Ordinary cross-thread success should not be treated as coverage of the side-parent opening-history fallback.

    No application files, permissions, configuration, or project code were modified for this investigation. This report was prepared with Codex assistance and posted at the user's request. It excludes actual conversation IDs, private prompts, business data, credentials, local usernames/paths, and full logs.

  19. WantoChange commented on Oct 16, 2026

    @WantoChange

    Additional macOS confirmation: this is still reproducible on Codex desktop 26.1007.71326 (build 20398), observed on 2026-10-16 UTC (2026-10-15 PDT).

    Environment and trigger

    • macOS; bundled codex-app-tools 0.1.6. The cached and app-bundled server.mjs files have identical SHA-256 hashes.
    • A side conversation forwarding an explicitly authorized ordinary message to its existing local main conversation.

    Observed behavior
    Two actual calls failed with exactly:

    'sendRequest.bind' is not a function.
    

    One call supplied hostId: "local"; the other omitted hostId. The destination could be listed/read normally. Each failed send immediately followed a successful thread/turns/list response in the desktop log, then the tool returned success=false. A subsequent destination read did not show the forwarded message. No further live messages were sent for diagnosis.

    Installed-code evidence in this build
    In webview/assets/app-initial-1ab6fbe93c4f.js, the origin-check helper Noc obtains an RPC proxy through Dg and passes r.sendRequest.bind(r) to the thread-item reading helper when opening history is unloaded.

    In webview/assets/app-shared-8340f229c2b3.js, the proxy appends chained property accesses to the remote method path. The resolver permits only own properties when traversing a function, excluding inherited Function.prototype.bind. The call therefore resolves the remote path sendRequest.bind and constructs the exact error reported above. This supports the previously discussed diagnosis of an RPC/local-function mismatch in the side-conversation origin check, before message dispatch.

    Isolated verification
    The shipped pure property resolver and Proxy traps were extracted into memory and exercised with local test doubles, without network requests or real message sends:

    • rpc.sendRequest.bind(rpc) produced the path sendRequest.bind and reproduced the exact error.
    • (...args) => rpc.sendRequest(...args) produced the path sendRequest; the local test-double call succeeded.

    Please include this macOS build in regression coverage for the paginated/unloaded opening-history fallback. The expected result is delivery or queuing of the authorized message with an accurate receipt.

    Limits and privacy: no live exception stack was captured, the installed app was not patched or restarted, and a patched-app end-to-end send was not tested. The forwarding closure has only been verified in isolation. This report was prepared with Codex assistance and posted at the user's request. It excludes conversation transcripts, raw logs, private thread IDs, account details, credentials, server addresses, and business repository information.

  20. joy648759-ux commented on Oct 17, 2026

    @joy648759-ux

    补充 Windows 当前版本复现及实际安装包 RPC 的离线验证(2026-10-17)。此反馈经用户授权,由 Codex 协助整理。

    环境:Windows x64;应用更新器报告桌面版本 26.1013.31256、build 20586、prod、up_to_date。Windows 安装包版本为 26.1013.3656.0,这是另一版本字段。

    实际现象:临时侧聊调用 send_message_to_thread,显示 'sendRequest.bind' is not a function.。本地桌面日志在 2026-10-17T00:54:19.936Z 和 00:57:36.068Z 记录两次发送失败,前面均有成功的 thread/turns/list。这些日志没有异常栈。读取失败源聊天返回 ephemeral threads do not support thread/turns/list;普通持久主聊天之间另有发送成功记录,不能将普通发送成功视为侧聊路径已修复。

    当前安装包证据:

    • webview/assets/app-initial-df84a35d942d.js:Vh 返回 AppServerManager RPC stub;Xeu 在消息发送前核对 sideConversation/父聊天关系,必要时调用 Zeu。Zeu 的 openingTurn 未加载、分页历史分支,在成功调用 listThreadTurns 后,将 r.sendRequest.bind(r) 传给条目读取 helper ix。
    • webview/assets/worker-3fe306248590.js:RPC proxy 将字符串属性链解析为远程方法路径;函数的继承属性不在可调用的自有属性内。因此 .sendRequest.bind 被解析为远程路径并产生相同 TypeError。

    离线验证比静态推断多做了一步:只读提取本机实际安装的 RPC 实现,以及原始 ix、Zeu,在独立 Node VM 中运行。原版 Zeu 的未加载 opening-history 分支确定性复现完全相同的错误。候选只在该函数中替换一处回调表达式:

    - r.sendRequest.bind(r)
    + (...args) => r.sendRequest(...args)

    11 项检查通过、0 失败,并由独立复核者再次实际运行通过。包括 3 项 RPC 检查和 8 项实际函数分支检查:原错误复现、参数/返回值与异常传递、opening history 已加载/未加载、空历史、分页及 compaction 过滤、请求参数、重复 cursor 保护。此计数不是完整应用集成测试。

    资产 SHA-256,供维护者识别本次构建:

    app-initial-df84a35d942d.js
    d7659a96f7d0cfe2249e089ef19675d09d04d6dd9569b550ddaa64722d4f13f3
    worker-3fe306248590.js
    d586e2bf94658bab36087ba9c56ae847f379fe318006f1da077219d0d488dd09
    

    验证边界:主机选择、输入来源解析及部分上下文是测试接缝;未执行完整 Xeu、真实消息发送、真实侧聊来源解析或非分页历史加载分支;没有捕获原线上异常栈。未修改、重新签名或重启已安装应用,未修改业务数据库。候选离线通过不等于已部署修复。

    请在受支持的 Windows 修复版本中核验:侧聊向已有父聊天交接,父聊天 opening history 已加载及未加载/分页两种情况;保留原有祖先关系与权限检查;正确传递读取异常;只产生一次目标消息并返回准确回执。也请告知包含修复的版本或受支持的临时解决方法。

    此评论不包含客户内容、真实聊天 ID、账号信息、凭据、私人路径、原始截图或完整日志。


    补充核查(2026-10-17 09:01 UTC):官方 prod 新更新包仍含相同缺陷;以下为未安装新版的离线验证。

    官方 production Windows 更新源此时返回包版本 26.1013.4894.0、releaseVersion 26.1013.40934。只读提取该官方 x64 MSIX 的 AppxManifest 和 app.asar,包内 package.json 确认为桌面版本 26.1013.40934、build 20770、prod。来源为应用内配置的官方地址:

    新包的 webview/assets/app-initial-5851df3f6cb1.js 中,Zeu 的 opening-history fallback 仍将 r.sendRequest.bind(r) 传入 ix。本次从新包重新提取实际 Zeu、ix 和 RPC 实现,在隔离 Node VM 中运行,原函数仍确定性抛出 'sendRequest.bind' is not a function.。转发回调候选仍只改测试副本中的一处表达式,11 项离线检查通过、0 失败。未将离线通过当成实际应用修复。

    新包资产 SHA-256:

    app-initial-5851df3f6cb1.js
    c70d95da34ba7e5962a559dbf68d0102d10b4b47b877f5d9933629bb5a1f3a10
    worker-3fe306248590.js
    d586e2bf94658bab36087ba9c56ae847f379fe318006f1da077219d0d488dd09
    

    该 RPC worker 与前述已安装版本的 SHA-256 完全相同。测试接缝和边界同前述说明;本次没有安装或运行新版桌面应用,没有新增真实消息测试,没有修改现有应用、权限或业务数据。此结果证明新包中同一离线故障仍在,不是新版实际侧聊发送的现场测试。请提供包含原生侧聊交接修复的受支持版本,并在 opening history 未加载/分页的真实场景验证准确且仅一次送达。

  21. Andrew1957 commented on Oct 18, 2026

    @Andrew1957

    Additional Windows reproduction on 2026-10-18 (UTC+08:00), posted at the user’s request with Codex assistance.

    Environment

    • Installed Windows x64 package: OpenAI.Codex_26.1013.3656.0.
    • Desktop logs: build 20586, commit f07f286327f3c9ef2b2f799b64b0393fdc1bdeed.

    Observed failure
    A side conversation forwarding an explicitly authorized message to its existing active local main conversation repeatedly returns 'sendRequest.bind' is not a function. from send_message_to_thread. Both supplying hostId: "local" and omitting it fail. list_threads succeeds. No successful delivery receipt is returned.

    Read-only desktop-log correlation:

    2026-10-18T04:50:28.728Z send_message_to_thread renderer execution started
    2026-10-18T04:50:28.747Z thread/turns/list response errorCode=null
    2026-10-18T04:50:28.767Z send_message_to_thread success=false
    
    2026-10-18T04:58:52.783Z send_message_to_thread renderer execution started
    2026-10-18T04:58:52.790Z thread/turns/list response errorCode=null
    2026-10-18T04:58:52.809Z send_message_to_thread success=false
    

    The exact exception comes from the tool results; these log lines do not contain a live exception stack.

    Shipped-code observation
    In webview/assets/app-initial-df84a35d942d.js, Xeu() resolves side-chat ancestry through Zeu(). In the unloaded opening-history fallback, Zeu() calls listThreadTurns(...) and then passes r.sendRequest.bind(r) to ix(...), with r = Vh(...) returning a host RPC proxy. The proxy in app-shared-2f18b1632f37.js maps string property chains to remote paths. This independently matches the RPC/local-function mismatch already discussed here. Please retain regression coverage for unloaded/paginated opening history, not only ordinary cross-chat delivery.

    Limits
    This report adds actual failures on the above installed Windows build plus read-only bundle inspection. It does not claim a live stack trace, a controlled version bisect, an isolated patch test, or patched-app end-to-end verification. No application files, permissions, configuration, or business code were changed. A forwarding callback or supported RPC item-reading interface remains a candidate for maintainers to validate.

    Expected: deliver or queue the authorized message exactly once and return an accurate receipt. This public comment excludes real thread IDs, private prompts, account details, local personal paths, server addresses, credentials, screenshots, and full logs.

  22. kexu818 commented on Oct 18, 2026

    @kexu818

    Additional macOS evidence on October 18, 2026.

    • Installed desktop: 26.1013.40934, build 20770, production channel. The app's supported update checker reports up_to_date for its configured channel.
    • Bundled/cached codex-app-tools manifests both identify version 0.1.6.
    • Two previous side-chat sends returned 'sendRequest.bind' is not a function. Desktop logs show successful thread/turns/list immediately before both failed tool responses. No live exception stack was captured.

    Read-only inspection of this build identifies the same path described above: the cross-thread routing function Xeu can call the opening-context resolver Zeu. For an unloaded opening turn, Zeu obtains an AppServerManager RPC proxy via Vh, lists the first turn, then passes r.sendRequest.bind(r) to the item reader ix.

    The shipped RPC property resolver permits only own properties on functions; inherited Function.prototype.bind does not resolve. Its call handler produces the reported error for the remote path sendRequest.bind.

    A local isolated fixture using the installed Zeu and relevant RPC traversal/call code reproduces the exact error. Replacing only the callback expression with (...args) => r.sendRequest(...args) passes that fixture. The transport and item-read bridge are synthetic; this is not a patched-desktop end-to-end test.

    A separate ordinary persistent chat successfully delivered the authorized message through the same native tool. Reading the destination confirmed the complete payload once. This does not verify the failing side-chat opening-history branch or prove the bug has been fixed.

    Please provide a supported desktop fix release, preserving the existing source/ancestry and authorization checks. Regression coverage should include unloaded/paginated opening history and accurate exactly-once delivery receipts.

    No installed app, permissions, global configuration, or conversation database was modified. No restart or experimental signed application copy was used. This report omits private conversation IDs, messages, account details, local paths and raw logs.

  23. LBatsoft commented on Oct 19, 2026

    @LBatsoft

    Additional macOS reproduction and offline candidate-fix validation, October 19, 2026.

    Environment and observed failure

    • Desktop version 26.1007.71326, build 20398, macOS arm64.
    • Cached codex-app-tools version 0.1.6.
    • An explicitly authorized side-chat message to an existing local main chat repeatedly failed with 'sendRequest.bind' is not a function.
    • Reading that destination through read_thread succeeded. Desktop logs show a successful thread/turns/list response immediately before each failed send response. No live exception stack was captured.

    Installed-build evidence and candidate change

    In webview/assets/app-initial-1ab6fbe93c4f.js, the side-chat opening-history resolver Noc first obtains a host RPC stub, then uses listThreadTurns to find the opening turn. Its unloaded/paginated-history branch passes r.sendRequest.bind(r) to the item reader CHe (exported from nB in app-shared-8340f229c2b3.js).

    The actual property traversal function aFt in that shared asset excludes inherited function properties. Consequently, attempting .bind on the remote function stub addresses the remote path sendRequest.bind, rather than invoking local Function.prototype.bind.

    Candidate change, confined to this callback expression:

    - CHe(r.sendRequest.bind(r), n, a.id, o, {timeoutMs: Ole}, 2, "asc")
    + CHe((...args) => r.sendRequest(...args), n, a.id, o, {timeoutMs: Ole}, 2, "asc")

    Please keep the existing source/ancestry checks and RPC own-property restrictions. This proposal does not broaden RPC access to inherited properties.

    Offline verification

    A local Node VM fixture reads, without modifying, the installed ASAR and evaluates its actual Noc, nB, and aFt functions. Only the candidate resolver's callback is replaced in memory. The original deterministically reproduces the exact reported error. Twelve checks pass:

    1. Original unloaded-history branch reproduces the exact error before requesting items.
    2. Candidate resolves the parent and preserves the RPC receiver, arguments and timeout forwarding.
    3. Loaded opening input avoids RPC.
    4. Loaded tool output retains precedence over input.
    5. Empty turn history returns null.
    6. A compaction-only page advances to the opening user message.
    7. Exhausted compaction-only history returns null.
    8. Item-read permission errors propagate unchanged.
    9. Unexpected-turn items are rejected.
    10. Repeated opening cursors are rejected.
    11. Unchanged item cursors are rejected.
    12. Oversized item responses retain the existing smaller-page retry.

    The RPC transport, local value-type classifier, host selection, envelope decoder and timeout constant are test seams. The fixture does not execute the complete send/routing path, real envelope parsing, non-paginated history loading or a patched desktop application. This is candidate-fix evidence, not an end-to-end fix claim.

    Asset SHA-256:

    app-initial-1ab6fbe93c4f.js
    f3d5fedc993d0ead2720c9877d8c72a82dc5fb2d935f13ad9426e6964fb6f105
    app-shared-8340f229c2b3.js
    3b4cabc382e71f0da7398393a619d7c62d13dfae598a5fe2e9880ab8d31d1bf5
    

    Separately, the application's bundled codex queue --thread <existing-thread-id> --message <text> successfully queued the authorized message. Reading the target confirmed the complete message and a new active processing turn. This verifies a workaround, not the failing desktop branch.

    Please validate the callback change in the maintained desktop source, including loaded and unloaded/paginated opening history, ancestry checks, propagated read failures, and exactly one target message with an accurate receipt. The public repository's contribution policy currently excludes external PRs, and the affected desktop module was not found in the public tree, so this is supplied as analysis for the existing issue.

    No installed application, permissions or global configuration was modified, and conversation storage was not edited directly. This report omits real chat IDs, private prompts, personal paths, account details, credentials and raw logs.

  24. luziyi123448-gif commented on Oct 20, 2026

    @luziyi123448-gif

    Confirming this on Windows again on 2026-10-21 (UTC+08:00). This is additional evidence for the existing issue, not a separate bug or a claim of a deployed fix.

    • OS: Windows 11 Pro x64, 10.0.26100.
    • Running application's Windows package: OpenAI.Codex_26.1013.4894.0_x64, established from the running executable path; this is the package version, not an About-dialog version.
    • From a side conversation, two explicitly authorized send_message_to_thread calls to an existing local main conversation failed with 'sendRequest.bind' is not a function. One specified hostId: "local"; the other omitted it. read_thread for the destination succeeded. Neither send returned a successful delivery receipt.

    Read-only inspection of this package finds the same previously reported path in webview/assets/app-initial-5851df3f6cb1.js: Xeu() can invoke Zeu() while resolving side-conversation ancestry. When the opening turn is unloaded, Zeu() obtains an RPC stub through Vh(), calls listThreadTurns(), then passes r.sendRequest.bind(r) to the item reader ix().

    I also ran an isolated in-memory test using this installed package's actual Zeu() and RPC implementation from app-shared-bbfeca5e5737.js, with synthetic host data and a mocked item-reader seam:

    Check Result
    Original resolver, unloaded opening turn Exact error reproduced: 'sendRequest.bind' is not a function.; the fake target recorded listThreadTurns but no item request
    Replace only r.sendRequest.bind(r) with (...args) => r.sendRequest(...args) in memory Synthetic parent resolved; fake target recorded thread/items/list
    Original resolver, already-loaded opening input Synthetic parent resolved without RPC calls

    This agrees with the existing diagnosis: the RPC proxy treats sendRequest.bind as a remote property path, not local Function.prototype.bind. The candidate change should preserve the existing RPC own-property restrictions and ancestry/authorization checks.

    The offline test does not exercise the complete live send path, the real item-reader/ancestry-envelope parser, or a patched desktop application. No live exception stack was obtained. The installed app, configuration, permissions, and conversation storage were not modified, and no additional live test messages were sent during diagnosis.

    Please include unloaded/paginated opening history in regression coverage for the supported desktop fix. Private conversation IDs, prompts, personal filesystem paths, project data, credentials, and raw session logs are omitted. Posted with Codex assistance at the user's explicit request.

  25. Taurusxw commented on Oct 21, 2026

    @Taurusxw

    Additional confirmation on Windows x64, observed October 21, 2026.

    Environment

    • Codex Desktop display version: 26.1013.40934, build 20770.
    • Windows package version: 26.1013.4894.0.
    • The installed executable has a valid OpenAI signature. The ASAR header matches the integrity hash embedded in that executable, and the affected script matches its archive integrity record.

    Observed failure

    From a side conversation, explicitly authorized calls to mcp__codex_app__send_message_to_thread targeting the existing main conversation repeatedly return:

    'sendRequest.bind' is not a function.
    

    The failure occurs both with hostId: "local" and with hostId omitted. Neither call returned a successful delivery receipt. Thread listing and status reads work; desktop logs show a successful thread/turns/list request immediately before the failed send response.

    Installed-code evidence and isolated validation

    In webview/assets/app-initial-5851df3f6cb1.js, Xeu invokes the ancestry resolver Zeu. Its unloaded, paginated opening-history branch obtains an RPC proxy through Vh, lists the first turn, and passes r.sendRequest.bind(r) to the item reader ix. This matches the RPC property-path problem already described in this issue.

    An isolated fixture executing the extracted installed resolver with a simulated RPC proxy reproduces the exact error. Replacing only that callback expression with (...args) => r.sendRequest(...args) passes eight checks covering the original failure, corrected request forwarding, cached context, ordinary opening messages, compaction pagination, delegation in tool output, empty history, and repeated-cursor protection.

    The fixture uses synthetic data and does not exercise the complete live send path. No candidate patch was installed or executed in the desktop application. No clean-install comparison was performed.

    Expected behavior: an authorized side conversation should deliver or queue the message and return an accurate receipt. Please include this Windows build and unloaded/paginated opening history in regression coverage, preserving the existing ancestry checks and RPC property restrictions.

  26. cain473-cmd commented on Oct 21, 2026

    @cain473-cmd

    Confirmed on Windows on 2026-10-21. This is additional evidence for the same side-conversation-to-parent delivery failure, including an idle parent.

    Environment

    • Desktop reported by check_app_update: version 26.1013.40934, build 20770, channel prod.
    • Windows package identity: OpenAI.Codex_26.1013.4894.0_x64 (different package and display version strings are reported as observed).
    • codex-app-tools cached plugin version: 0.1.6.
    • The configured updater returned up_to_date; this does not establish whether an unreleased fix exists.

    Reproduction / observed behavior

    1. Open an ephemeral side conversation from an existing local parent task.
    2. The human explicitly authorizes sending a follow-up to that parent.
    3. Call mcp__codex_app__send_message_to_thread with an existing parent ID and a normal text prompt.
    4. Observe isError: true and the exact message:
      'sendRequest.bind' is not a function.
      
    5. Omitting the optional hostId, changing prompt length, and navigating to the parent before retrying did not resolve the observed error.
    6. list_threads, read_thread, and navigation work. A bounded read after failed sends still showed the prior completed turn and an idle parent, with no new delivery receipt.

    The report concerns execution failures after authorization. Separate automatic-approval rejections also occurred during the session, but they are not counted as reproductions of this JavaScript error.

    Desktop log correlation (sanitized)

    Two failed sends at 2026-10-21T02:11:10.687Z and 2026-10-21T02:11:37.814Z show the same sequence:

    • dynamic_app_tool_renderer_execution_started, tool=send_message_to_thread
    • AppServerConnection response_routed, method=thread/turns/list, errorCode=null
    • Sending server response, tool=send_message_to_thread, success=false

    No application stack trace was available in the inspected log slice. No successful delivery was claimed.

    Static-code investigation / suspected fault

    Read-only inspection of the installed renderer bundle identified a side-conversation ancestry/opening-context helper, minified as Zeu. When openingTurn is null, it obtains a manager through Vh(...), calls listThreadTurns(..., itemsView: 'notLoaded', sortDirection: 'asc'), and then passes r.sendRequest.bind(r) to the item-loading helper ix(...).

    Vh(...) can return a host/manager RPC proxy. This is a plausible mismatch between an RPC method proxy and a normal JavaScript function supporting .bind, and the call order matches the observed successful thread/turns/list immediately followed by failure. This is a suspected location based on static code and logs, not a confirmed runtime stack diagnosis.

    Please inspect whether that callback should instead use a normal forwarding function, for example (...args) => r.sendRequest(...args), and add a regression test covering a paginated parent with null opening context accessed through the RPC-proxy path. Preserve ancestry checks and normal authorization behavior.

    Impact / safety

    Explicitly authorized work cannot be handed back from the side conversation to the parent. Repeated consent does not fix the runtime binding failure. No installed application code, plugin code, permissions, project/runtime state, or stored conversation history was modified to work around the error. No credentials, actual thread IDs, project code, financial data, or complete logs are included in this public report.

    Related later reproduction: #55023.

  27. johnlanni commented on Oct 21, 2026

    @johnlanni

    Additional macOS reproduction on 2026-10-21 (UTC+08:00), on desktop version 26.1013.40934, build 20770.

    Environment

    • Installed app display name: ChatGPT; bundle ID: com.openai.codex.
    • Version/build above were read from the installed application's Info.plist, not an update check.
    • macOS 26.3.2, arm64.
    • Source: a side conversation of an existing active local parent task.

    Observed behavior
    The user explicitly authorized sending findings back to the parent task. mcp__codex_app__list_threads succeeded and showed that parent as active.

    Two calls to mcp__codex_app__send_message_to_thread failed: the first supplied hostId: "local"; the second omitted it. Both used the same existing parent ID and ordinary text prompts, with optional model/thinking overrides omitted. The prompts differed in length, so this is not a controlled identical-payload comparison.

    Both returned exactly:

    {"content":[{"type":"text","text":"'sendRequest.bind' is not a function."}],"isError":true}

    A sanitized reproduction, from a side conversation after explicit user authorization:

    const result = await tools.mcp__codex_app__send_message_to_thread({
      threadId: "<existing-parent-thread-id>",
      hostId: "local",
      prompt: "Please review these findings when appropriate."
    });
    text(result);

    Expected: deliver or queue the authorized message and return an accurate receipt, or return an actionable supported-operation/state error.

    Neither observed call returned a successful delivery receipt. This report does not claim permanent non-delivery or a confirmed internal root cause; no destination-history read after these calls, regular-chat control, or runtime stack trace was collected. No extra live send attempts were made for this report.

    No app package, permissions, global configuration, project code, or conversation storage was modified. Real thread IDs, private prompts, personal paths, credentials, and full conversation logs are omitted. Reporting this reproduction on the existing issue rather than opening a duplicate.

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

    appIssues related to the Codex desktop appapp-serverIssues involving app server protocol or interfacesbugSomething isn't workingtool-callsIssues related to tool calling

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions