Skip to content

[macOS Desktop] Orbit catalog treats access-denied hydration as retryable and repeatedly reloads 65 chats #53677

Open

Description

@joshbonner

Summary

Codex Desktop on macOS repeatedly requests metadata for the same 65 cloud chats and receives -32003: thread access denied. A full restart does not stop the requests. Read-only inspection of this shipped build identifies the cloud “Your dot”/Orbit catalog refresh as a concrete retry path: a terminal permission failure is wrapped without an HTTP-style status, treated as retryable, and the catalog refresh can repeat every minute.

This report adds a specific caller/error-classification lead to #53178. Please consolidate if appropriate.

Environment

  • Codex Desktop: 26.1007.30912, build 20156, production channel.
  • Desktop build commit: a993bdbe5bb9503cb84de1e67d5635cf186a959f.
  • Bundled app-server: 0.162.0-alpha.17.2.
  • macOS 26.6.2 (25G83), Apple Silicon.
  • Observation date: October 13, 2026.
  • A second Mac's connected app-server reports the same bundled version. Direct inspection of that Mac was unavailable; the user also reports similar warnings there.

Observed behavior and measurements

Existing-profile observation, not a clean-install reproducer:

  1. Leave the desktop app open with existing cloud “Your dot” chats.
  2. Observe repeated background metadata reads failing with the fields below.
  3. Fully quit and reopen Desktop.
  4. The denied-read traffic returns.

From 00:17:30.411 through 13:53:03.813 UTC on October 13:

  • 14,637 distinct failed request IDs across 65 distinct chat IDs, observed across three renderer IDs.
  • Errors consistently include:
    method=thread/read
    source=thread_hydration
    priority=background
    error.code=-32003
    error.message="thread access denied"
    
  • The same IDs recur in batches. Later minute buckets contained 260 failed reads per minute; multiple renderers and retry attempts mean this is not claimed to be exactly one request per chat per minute.
  • A persisted cloud sidebar catalog contains 46 of the denied IDs as thread records. Other denied IDs appear in output-related cached references.
  • The cached catalog's account/user identifiers match the local authentication claims; a simple stale-account mismatch was not found. This does not establish that every cloud authorization context is correct.

In the inspected October 13 logs up to the same cutoff, there were also 103 distinct queue-full rejections: 94 account/read, 3 thread/read, 2 thread/items/list, and one each for config/read, mcpServerStatus/list, thread/turns/list, and fs/readFile. Queue snapshots show four requests in flight and 64 queued interactive requests. The most recent rejection in this window was at 13:42:15.056 UTC, shortly after app startup.

The user reports intermittent general app slowdown. The denied-read loop is unnecessary background work, but these observations do not prove it directly caused all queue-full events or all slowdown. In particular, most queue rejections concern account reads and warrant separate investigation.

Shipped-code investigation lead

Read-only inspection of webview/assets/app-shared-8bd9d0399038.js found:

  • The cloud-aeon-sidebar-threads query fetches Orbit profile/thread attachments, combines them with previously cached thread references, and calls hydratePinnedThreads(ids, {throwOnReadError: true}).
  • Hydration uses at most two concurrent reads per batch. It collects failures and throws the first error after processing the batch.
  • The query wraps that error in a catalog error class (_4). Its status comes only from an existing numeric error.status; it does not map JSON-RPC -32003 / thread access denied to a terminal authorization state.
  • The generic retry predicate (Bq) retries errors with no numeric status, up to three retries. Numeric 401/403/404 statuses would be non-retryable.
  • The catalog sets refetchInterval to one minute when that same predicate says its error is retryable. It also refetches on mount, focus, and reconnect.
  • The general cloud read cache retains normalized thread_not_found errors, but not access denial. Explicit shared reads bypass that terminal-error cache.
  • A failed catalog refresh does not commit a reconciled catalog, allowing old cached references to remain candidates for later refreshes.

These branches explain how a permanent access denial can become a recurring batch refresh. The actual failing wire payloads and backend authorization decisions were not captured, and this is not proof that the catalog is the only caller responsible for every logged request.

Expected behavior / requested fix

  • Represent access denial as a terminal unavailable state until identity/access changes or the user explicitly retries.
  • Handle inaccessible entries independently so one denial does not repeatedly fail and reload the entire catalog.
  • Reconcile stale catalog references while preserving original chats and server authorization boundaries.
  • Coordinate/deduplicate background reads across renderers.
  • Investigate the separate startup account/read fan-out and queue-full rejections.
  • Provide a supported recovery path that preserves chats and active work.

Related reports

Privacy and interventions

No application bundle, signature, credential store, chat database, cloud chat, or access policy was modified. No patched app was installed. The investigation used read-only app/log/cache inspection and a short-lived diagnostic app-server to read effective configuration layers; that server was shut down.

No private chat/request/account IDs, titles, conversation contents, local paths, credentials, raw logs, or screenshots are attached. Prepared and submitted by Codex with the user's authorization.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    app-serverIssues involving app server protocol or interfaces
    dotsIssues involving setting up ChatGPT dots or managing their ongoing work.
    on Oct 13, 2026
  2. photosamurai commented on Oct 15, 2026

    @photosamurai

    Additional evidence from macOS Desktop 26.1007.71326, build 20398, observed October 15, 2026. The configured updater reports up_to_date. Platform: Apple Silicon, macOS 27.0 (26A428).

    Same retry pattern in this build

    A bounded review of retained main-process logs from 2026-10-15 00:00:57.655 through 13:18:03.956 UTC found 9,357 distinct failed request IDs across 22 chat IDs. Counted entries have:

    method=thread/read
    source=thread_hydration
    priority=background
    error={"code":-32003,"message":"thread access denied"}
    

    Failures occur across three window IDs. All 19 thread records in the persisted cloud sidebar catalog are among the 22 denied IDs. This is an existing-profile observation, not a clean-install reproducer.

    Direct access succeeds, background access still fails

    Using the supported read_thread(hostId="durable") tool, two affected chats successfully returned their existing history. Corresponding thread/read responses had errorCode=null at 13:18:06.831 and 13:18:08.363 UTC, followed by successful turn/item reads.

    After those successful reads, each same chat produced four further denied background hydration requests, with the latest at 13:19:18.169 and 13:19:18.466 UTC. Direct reads therefore demonstrate access through that path but do not stop background retries. They do not establish which request parameter, transport, or server context differs.

    Current-build source confirmation

    Read-only inspection of the installed app-shared-8340f229c2b3.js confirms that the catalog mechanism described in this issue remains present in build 20398:

    • cloud-aeon-sidebar-threads merges cached thread references into the hydration candidates and calls hydratePinnedThreads(g,{throwOnReadError:!0}).
    • Its error wrapper (_4) copies an existing numeric status; it does not itself map JSON-RPC -32003 to a terminal HTTP-style authorization status.
    • The default retry predicate Bq allows up to three retries for errors without a numeric status. The catalog's refetchInterval returns one minute when the query is in error and Bq(0,error) permits retry; it also refetches on mount, focus, and reconnect.
    • The general read cache preserves normalized thread_not_found errors, while durable shared reads bypass the memoized read path. Access denial is not suppressed equivalently.
    • This identifies a concrete recurring-request path, not the only possible caller and not a demonstrated freeze mechanism. The custom-sidebar hydration query is a separate path with different error handling.

    Concurrent window-input freeze; causal link not established

    The user reports intermittent freezes requiring force quit in previous occurrences. During this occurrence, one window stopped accepting clicks and typing while the native macOS menu bar remained usable. A newly opened window works and was used for this investigation. This overlaps the symptom in #53707.

    Evidence limits:

    • Denied reads also occur in the working new window. Their presence alone is insufficient to explain a freeze.
    • The counted denied requests had median queue wait 0 ms, maximum 3 ms. No queue-full messages were found in the reviewed main-process files. This does not demonstrate a sustained backlog.
    • An initial renderer CPU observation was 94.6%; later measurements were near idle. Samples of both original renderers showed their main threads mostly waiting in native event handling. No persistent JavaScript loop was demonstrated, and the renderer PIDs were not conclusively mapped to the frozen visible window.
    • 238 ResizeObserver errors were recorded for the original window, latest at 13:03:32.618 UTC. They precede the reported freeze but do not establish its trigger.
    • Reload Window is present behind allowWindowReload in the shipped menu implementation, but the user confirms it is absent from View and Command+Control+R has no effect in this installation. It is not an available recovery here.

    Please investigate the authorization/access-context contrast and terminal-error retry handling described above, provide a supported mitigation that preserves original chats, and investigate window input/focus recovery separately unless a causal connection is demonstrated.

    No installed app files, signatures, credentials, access policies, chat databases, or original chats were modified. No raw logs, private chat/request/account IDs, titles, conversation contents, screenshots, or personal filesystem paths are included. Prepared and submitted by Codex with the user's authorization.

  3. honghaoaa1230 commented on Oct 15, 2026

    @honghaoaa1230

    Additional affected macOS profile on ChatGPT/Codex Desktop 26.1007.71326, build 20398 (bundle ID com.openai.codex), observed October 15–16, 2026, UTC+8. Platform: Apple Silicon, macOS 27.0.1 (26A434); Codex Framework 155.0.8059.40.

    Bounded measurements

    Across the retained main-process log segments for one app run, from 2026-10-15 03:49:02.526 to 16:10:52.495 UTC:

    • 10,898 failed log rows = 10,898 distinct request IDs, targeting 6 distinct cloud chat IDs.
    • Requests appear across 3 renderer/window IDs.
    • Each counted row has method=thread/read, source=thread_hydration, and error.code=-32003 / error.message="thread access denied".
    • These same six IDs account for all six thread records in the persisted cloud-aeon-sidebar-cache-v1 for host durable.
    • The cache's refreshStartedAtMs still corresponds to 2026-10-08 12:04:40 UTC+8, a week before this capture. Cached profiles associate the six records with the same active root thread.
    • The denied-read queue waits are at most 3 ms in this bounded capture. This does not establish queue saturation.

    Source confirmation / recovery concern

    Read-only inspection of this installed build's app-shared-8340f229c2b3.js confirms the issue's concrete retry path:

    1. The cloud catalog adds cached thread IDs back to its hydration candidates, including IDs absent from a newly fetched catalog.
    2. It calls hydratePinnedThreads(..., {throwOnReadError:true}).
    3. Its catalog error wrapper copies a numeric status if present. The logs show Orbit catalog task metadata could not be loaded ... status=undefined alongside these denials.
    4. The generic retry predicate accepts errors without numeric status for up to three retries; the catalog additionally schedules a one-minute refetch when that predicate allows it, plus mount/focus/reconnect refetches.
    5. The failed refresh does not reach the final reconciled-cache write, leaving old IDs eligible for later attempts.

    This corroborates the source path reported above; it is not a wire capture proving which caller accounts for every request. The backend reason for the access denial remains unknown.

    CPU observations and limits

    During short local measurements the main renderer ranged from approximately 10–24% CPU, with one earlier two-second sample at 85.8%, and approximately 2.1 GiB physical footprint. Percentages are per logical core. These observations do not quantify the retry loop's CPU contribution. A separately identified Safari WebKit process was also consuming significant CPU; all system load and fan activity must not be attributed to Codex.

    Please provide a supported way to stop this denied-background-read loop without deleting original chats, modifying app bundles or credentials, weakening authorization, or interrupting active local work/deployments. In particular, handle access-denied entries independently, stop retrying terminal denial until relevant access/identity changes or explicit retry, and allow stale catalog state to reconcile.

    No app bundle, credential store, chat database, access policy, original cloud chat, or running task was changed during this capture. This is an existing-profile observation, not a clean-install reproducer. No raw logs, screenshots, private chat/account/request IDs, chat titles/content, or personal filesystem paths are included.

    Prepared and submitted by Codex on the user's explicit request to report this bug to OpenAI.

  4. ciwei0600 commented on Oct 16, 2026

    @ciwei0600

    Additional evidence on macOS 26.5 (25F71), Desktop 26.1007.71326, build 20398. Observed October 16, 2026, UTC+8. The configured updater reports up_to_date.

    The repeated background denial remains reproducible in this existing profile. Eleven remaining cloud targets each produced 29 distinct failed requests in a bounded ten-minute baseline. A later two-minute check still contained failures for all eleven targets. Relevant fields are:

    method=thread/read
    priority=background
    source=thread_hydration
    error.code=-32003
    error.message="thread access denied"
    

    A fresh supported read_thread(hostId="durable") successfully retrieved an existing turn and idle status for one of the same targets; background hydration for it continued to fail. Opening a durable deep link, both with and without an explicit shared parameter, did not restore UI loading. A previous app restart also did not resolve the loop.

    Read-only inspection of this installed build confirms the catalog path described in this issue: retained cached IDs re-enter hydration, hydratePinnedThreads is called with throwOnReadError:true, the error wrapper copies only an existing numeric status, and an unclassified denial remains eligible for three retries plus the catalog's one-minute periodic refresh. A failed refresh does not reach the final reconciled-cache write.

    An offline check evaluated the actual extracted readThread method, error classifier, and retry predicate against a fake transport, with no live app or network access:

    • Eleven synthetic IDs over five scheduling cycles: 55 transport requests for access denial, both with default access and explicit shared access.
    • Control using the normalized thread-not-found error with default access: 11 transport requests.
    • The actual generic retry predicate permits attempts 0–2 for an error without numeric status; a numeric 403 control is non-retryable.

    This isolates the retry-classification gap. It does not prove the backend cause of the first denial, identify the caller of every observed request, or quantify its contribution to overall slowness. Failing wire payloads and backend authorization decisions were not captured.

    Please provide a signed client/service fix or a supported live recovery that preserves existing chats and active work. In particular: reconcile owned/shared access correctly, classify explicit denial per entry, allow other catalog records to update, and coordinate denial suppression across windows without blocking explicit foreground retry or active turns.

    No installed app files, signatures, credentials, databases, caches, access policies, or original chats were modified in this follow-up. No active task was interrupted. This draft contains no private chat/request/account IDs, titles, project names, conversation contents, personal paths, screenshots, credentials, raw logs, or installed source excerpts.

    Prepared and submitted by Codex with the affected user's explicit authorization.

  5. 0xdevalias commented on Oct 17, 2026

    @0xdevalias

    Independent build-20398 confirmation and clarification of retry cardinality.

    The actual Bq retry predicate returns true at failure counts 0,1,2 and false at 3 for {code:-32003,message:"thread access denied"}: initial attempt plus three retries = up to four attempts per failed query batch. A batch can read multiple threads; multiple renderers and minute-based catalog refreshes multiply totals. Numeric HTTP 403 is terminal, but this JSON-RPC error has no numeric HTTP status for the wrapper/predicate. This does not establish token expiry.

    Across the examined interval, 30 thread IDs were denied; 15 occurred in cached/pinned/order/reference state and six also existed in the local thread database unarchived. Local presence does not grant access on the durable service; cached local references can still be offered to remote hydration. The server's generic denial omits its specific authorization decision, so these observations do not distinguish obsolete host/reference/account scope or other backend policy reasons. It is not evidence of a macOS filesystem lock.

    The actual durable readThread method repeated five transport requests in five synthetic access-denied cycles, including explicit shared access; a normalized thread-not-found control made only one call because it was retained terminally. Live denials had median queue wait 0 ms, maximum 5 ms, median response about 49 ms: unnecessary recurring traffic, but not proof of continuously saturated queues or the initiating cause of a separate local send stall.

    A different UI banner, This is open in another app, uses AUs in app-initial-1ab6fbe93c4f.js, matching already has an active writer or already has a live local writer; the resume hook marks writer conflict. Please keep that single-writer conflict distinct from catalog read authorization and frontend owner/follower stream roles.

    Suggested fix: classify this access-denied code terminally for the affected host/account/thread/access scope, stop rehydrating it until meaningful identity/access change or explicit retry, reconcile stale references without deleting original conversations, and expose a sanitized denial reason. Do not change authorization scope merely to bypass the failure. Source and actual-code retry/read probes are included in #53197 (comment); the shared host scheduler problem is related load, not a proven common cause.

    Verified 2026-10-17: Codex Desktop macOS arm64 26.1007.71326, build 20398, macOS 26.6 (25G72). Installed archive Contents/Resources/app.asar SHA-256 2f231a64e6dd30111bcd09e03c149cd06c8679b25914842772423251c4608ded.

    Build-specific source provenance:

    • webview/assets/app-shared-8340f229c2b3.js: SHA-256 3b4cabc382e71f0da7398393a619d7c62d13dfae598a5fe2e9880ab8d31d1bf5.
    • .vite/build/main-CwxgTOle.js: SHA-256 87d52265eb13608a380fabcac47ecf13a39b981115c0960c18af563ea6d32d51.
    • .vite/build/src-DCNiwad_.js: SHA-256 86fb2066bbc2f7428864b76b46ef570b09eb1e92e81e9d6f089f5b048a66df25.

    Source observations below are version-specific. Offline probes evaluate extracted shipped methods in a Node VM with synthetic dependencies; they do not establish an unlogged live race. No app patch/restart, queue edit, direct send, or SQLite mutation was performed. Private text, annotations, account identifiers, task IDs, and raw logs are excluded.

  6. dandelionxuan123-netizen commented on Oct 17, 2026

    @dandelionxuan123-netizen

    Windows 当前版本仍反复读取访问被拒的聊天;同一台机器此前已累计三万多次

    这是本问题在 Windows 当前客户端上的补充证据。用户报告该问题已持续数日;当前新启动窗口中的数百次失败不能代表此前长期运行时的严重程度。

    当前环境与观察

    • Windows 桌面安装包:OpenAI.Codex 26.1013.4894.0。
    • 实际官方 CLI/core 报告:0.163.0-alpha.10.2;桌面与 CLI 版本分别记录。
    • 同一次桌面启动,从 2026-10-17 20:47:13 到 21:08:41(UTC+08:00)的有界观察已记录 764 个不同的失败请求 ID,涉及同一批 191 个云聊天。
    • 失败签名:method=thread/read、priority=background、source=thread_hydration、code=-32003、message="thread access denied"。
    • 前三个批次中,原窗口读取 191 次;用户确认新开窗口后,原窗口又读取 191 次,新窗口再读取 191 次。后来又出现一批 191 次拒绝。
    • 没有发送模型任务或重放失败请求来触发验证。不能把所有重复直接归因为无操作定时器。
    • 用户没有报告这台机器界面卡顿;本报告只处理后台重复读取及额外网络请求。未测量流量字节,未声称队列饱和或这些请求解释所有流量。

    同一台机器的历史严重程度

    本次重新读回同一台 Windows 机器保存的历史诊断回执,确认以下记录。时间统一为 UTC+08:00:

    观察时间或窗口 失败事件数 不同聊天数 计数范围
    2026-10-14 16:35:55 快照 25,806 179 旧桌面会话的累计完整拒绝事件
    2026-10-14 16:40:46 快照 27,076 179 同一累计计数的后续快照
    2026-10-14 16:58:07 快照 32,625 179 同一累计计数继续增长;不是额外新增 32,625 次
    2026-10-17 08:00:00–11:49:24 10,368 190 今日较早的另一个桌面会话日志窗口
    2026-10-17 20:47:13–21:08:41 764 191 当前版本的新启动会话,已确认 764 个不同请求 ID

    旧回执的计数定义仅包含完整 Request failed、method=thread/read、source=thread_hydration、code=-32003、message=thread access denied;没有把 response_routed 再计一次。10 月 14 日的旧计数未在本轮重新逐请求 ID 去重,因此按历史完整拒绝事件报告,不冒称已重做全量独立去重。10 月 17 日较早窗口另有两次 app-server unavailable,它们不包含在 10,368 次访问拒绝中。

    这些快照和不同会话窗口不相加成一个总数;聊天集合可能跨会话重叠。记录支持“至少在 10 月 14 日与 17 日均存在,单个旧会话曾累计三万多次”,不证明中间每一分钟持续请求,也没有流量字节测量。旧会话的精确运行包版本未随本表重新核定,不能把当前版本追溯套用于全部历史记录。

    当前版本的本机对应证据

    只读核查当前安装包,发现:

    1. cloud-aeon-sidebar-threads 查询调用 hydratePinnedThreads,并在读取错误时让整个批次失败。
    2. durable 主机的该 hydration 路径显式提供 shared 访问模式。失败请求本身没有记录这个 wire 字段,故不把静态实现当作每条请求的抓包证明。
    3. 目录错误包装器只复制已有的 numeric status。本次四次目录刷新错误的实际日志均为 status=undefined,时间与失败批次末尾紧邻。
    4. 实际重试函数 dv 在失败计数小于 3 时接受无 numeric status 的错误;catalog 还有错误状态下一分钟刷新,以及 mount/focus/reconnect 刷新。
    5. 最终缓存提交在 hydration 成功以后;批次失败无法完成正常的 catalog reconciliation。

    之前修复的短名称仍保持,原正文未变;多条被拒记录原本也有短名称。补名称没有消除这个访问拒绝与重复读取问题。

    请求的修复或正式恢复办法

    请提供适用于 Windows 当前签名客户端或服务端的修复:

    • 正确区分 owner/shared 读取语义,保留服务端授权边界;不要通过跳过拒绝或扩大权限获取结果。
    • 对明确访问拒绝按 account/host/thread/access 范围保存不可自动重试状态,逐条处理,不让一个拒绝反复重载整批。
    • 跨窗口协调与去重;在相关身份/权限变化或明确前台重试后才使该状态失效。
    • 允许正常条目完成目录同步,并给出不删除原聊天、不打客户端补丁的受支持恢复步骤。

    当前仍未知:服务端首次拒绝的具体授权规则;每条失败请求的完整 wire 参数;每次刷新具体由哪个调度事件触发。

    隐私与操作边界

    本次补充经用户明确同意,只发送脱敏文字。未包含私人聊天/请求/账号 ID、用户名、项目名、本机路径、正文、凭据、原始日志或截图。未修改客户端、数据库、缓存或安全策略;未删除或归档聊天。用户对新开窗口的时间确认与实际日志核对过。这里的隐私范围不包括任何另行由反馈界面自动附带的诊断内容。

  7. jrsarnold commented on Oct 17, 2026

    @jrsarnold

    Windows follow-up: the cloud-history retry problem remains after a targeted cache refresh and an alternate-network test on October 17, 2026.

    Environment: Windows 11 Pro 10.0.26300; desktop app 26.1013.31256, build 20586; MSIX 26.1013.3656.0; bundled CLI 0.163.0-alpha.10.2. The configured updater reported up_to_date earlier in this investigation.

    These are bounded observations of an existing profile, not a clean-install reproducer:

    Observation, UTC Denied background reads Distinct cloud chats Queue-full errors
    Before cache refresh, 15:53:31–15:58:31 950 Not counted in this baseline 0
    After restart, 16:00:17–16:05:17 1,144 88 0
    Phone hotspot, 16:20:51–16:25:51 348 87 0

    The counted failures are complete Request failed records for thread/read, source=thread_hydration, priority=background, code=-32003, message="thread access denied". Corresponding response_routed records are not counted again.

    The one cache intervention removed only electron-persisted-atom-state.cloud-aeon-sidebar-cache-v1 from the two global-state files while the app was closed. Backups, parsed-state preservation, and file ACLs were checked. The cache stayed absent but denied reads returned. On the phone hotspot, Ethernet was disconnected and the laptop's active route used Wi-Fi with a different gateway. The same denied IDs still recurred.

    An affected original cloud chat was missing from sidebar/search while list_threads and read_thread(hostId="durable") could retrieve it. The built-in thread-ID-only navigation selected hostId=local and failed with "no rollout found". A registered app link explicitly specifying hostId=durable then completed thread/read, turns/items reads, and resume; the user confirmed the original messages were visible. No further denials for that chat were observed in the following three-minute check; 87 others continued. That is a limited opening workaround, not a repair of the catalog.

    Current-build read-only source inspection found the same path described here: cloud-aeon-sidebar-threads calls hydratePinnedThreads with throwOnReadError; BGn preserves only an existing numeric status; retry predicate dv accepts errors without a numeric status; the failed query can refetch every minute. The real catalog warning at 16:00:30.695Z logged status=undefined. An offline probe of the installed pure retry functions accepted a synthetic -32003 error at failure counts 0, 1, and 2, rejected it at 3, and rejected numeric HTTP 403 immediately. This establishes retry classification, not the server's reason for the first denial or the caller of every request.

    Transport errors remain a separate question. The app logged ERR_SSL_BAD_RECORD_MAC_ALERT after restart, before the hotspot test. Ten public HTTPS downloads succeeded on each network; no new TLS/remote-offline/unknown-stream error was observed in the five-minute hotspot window. A read-only request through the desktop connection also succeeded. The user has avoided normal laptop-desktop integration because of the failures, so this is not a sustained workload or reliability validation.

    Please provide a current Windows fix or supported recovery procedure that preserves original chats and active work, and investigate catalog host/access propagation and retry classification. This report does not establish that the denial loop causes all disconnects.

    Only text observations, versions, counts, and sanitized error messages are included. No private thread/request/account IDs, chat titles or contents, personal paths, credentials, raw logs, screenshots, or app-state backups are attached.

  8. aiyouwei-laoshu commented on Oct 18, 2026

    @aiyouwei-laoshu

    Additional macOS confirmation on 2026-10-18: supported cloud reads succeed while background hydration continues to report access denied.

    Environment: desktop version 26.1013.40934, build 20770, production channel. The configured updater reported up_to_date during this diagnostic pass. This is an existing-profile observation, not a clean-install reproduction.

    Observed results:

    • The recent background-denial set contained 10 cloud threads.
    • All 10 returned successfully through the supported read_thread tool with hostId="durable". This establishes successful access through that read path, not complete historical recovery or verified UI rendering.
    • After those direct reads, a bounded two-minute log sample still contained 60 Request failed events covering those same 10 targets. This is a log-event count, not a daily total, a count of model turns, or an independently deduplicated count of request IDs.
    • The recurring failure fields were method=thread/read, source=thread_hydration, priority=background, error.code=-32003, error.message="thread access denied".

    No incorrect local host/ownership mapping was found for the sampled targets. That does not establish which authorization context or request parameter differs between the successful and failing paths. No failing wire payload was captured, and no single owner/shared-access explanation is asserted.

    Separate transport disconnections were observed earlier; the cloud connection subsequently recovered and a supported cloud read succeeded. Those transport errors should not be conflated with the continuing background access-denied responses.

    This diagnostic pass did not restart the app, clear caches, modify installed code or signatures, change credentials/configuration/authorization policies, or delete/archive chats. Earlier update/cache-refresh attempts on this installation had not resolved the recurring denial; no cache reset or restart was repeated in this pass.

    Please investigate the successful direct-read versus failing background-hydration context, bound repeated retries of authorization failures, and provide a supported recovery procedure that preserves original chats, configuration, and active work. Related: #53178 and #51675.

    Privacy: this comment contains only sanitized text and aggregate measurements. No files, screenshots, raw logs, conversation contents/titles, private chat/request/account identifiers, credentials, configuration files, or personal filesystem paths are attached or included. Submitted with the user's explicit authorization.

  9. efrasmsq-sudo commented on Oct 19, 2026

    @efrasmsq-sudo

    Windows confirmation: recurring denied hydration and installed-code retry probe (2026-10-19)

    Adding evidence to this existing report with the workstation owner's explicit authorization.

    Verified environment: Windows x64; installed MSIX package version 26.1013.4894.0; packaged desktop application version 26.1013.40934; executing backend reports codex-cli 0.163.0-alpha.10.2. These are different version fields, not interchangeable.

    Bounded observations

    • Re-reading four retained main-process log segments found 46,933 complete failure log rows across 59 distinct conversation IDs, between 2026-10-19 12:42:31.788 and 20:46:53.817 UTC.
    • Selection required Request failed, method=thread/read, source=thread_hydration, and -32003 / thread access denied. Corresponding response-routing records are not counted again. This is a log-row count, not an independently deduplicated request-ID count or a whole-day total; another segment was excluded from this baseline.
    • A separate later tail sample contained 258 denied rows involving 60 targets. Do not add the two samples as independent totals.
    • All 60 targets in that later sample were absent from the local threads table. Denied IDs also occurred in persisted cloud-sidebar, output, and subtask references. No private IDs or cache contents are included here.
    • Sampled queue waits were approximately 0–1 ms. This does not establish queue saturation or quantify the retry loop's CPU contribution.

    Confirmation in the installed build

    Read-only inspection of the relevant packaged JavaScript members, checked against their declared member hashes, found the same concrete path:

    1. cloud-aeon-sidebar-threads merges retained cached references into hydration candidates.
    2. hydratePinnedThreads(..., {throwOnReadError: true}) processes the batch and propagates a read failure. The durable-host branch already supplies shared access; this is not evidence that simply adding shared access fixes the denial.
    3. The catalog error wrapper BGn preserves only an existing numeric status. The bridge error conversion preserves the JSON-RPC code but does not turn it into an HTTP authorization status.
    4. Retry predicate dv treats an error without numeric status as retryable, and the catalog schedules a one-minute refetch for that error state, plus mount/focus/reconnect refreshes.
    5. Failure occurs before the final reconciled-cache write, leaving old references eligible for later attempts.

    An offline probe evaluated the actual extracted pure retry functions only, without application or network execution:

    Input Failure counts 0, 1, 2, 3
    JSON-RPC -32003: thread access denied true, true, true, false
    Numeric HTTP status: 403 false, false, false, false

    Thus the rejected query can make an initial attempt plus three retries, followed by another catalog refresh cycle.

    Requested correction and limits

    Please classify explicit denial per account/host/thread/access context, allow other entries to reconcile, and retry denied entries only after a relevant access/identity change or explicit foreground retry. Preserve original chats and authorization boundaries.

    The server's reason for the first denial remains unknown. No failing wire payload or backend authorization decision was captured; expired credentials, incorrect ownership, and local filesystem permissions are not established causes. Concurrent MCP accumulation is being reported separately in #51649; no causal link between that spawning and this denial loop is asserted.

    The follow-up was read-only. Selected helper processes had been terminated earlier in the incident; this is not a clean-install reproduction or a controlled restart/cleanup comparison. No installed code, credentials, database/cache contents, or access policies were changed during this diagnostic pass.

    Privacy: aggregate observations and generic error fields only. No private conversation/request/account identifiers, project names, chat contents, personal filesystem paths, credentials, raw logs, screenshots, or attachments are included.

  10. janozeli commented on Oct 20, 2026

    @janozeli

    Linux confirmation: repeated access-denied background hydration on 26.1013.40934

    Environment: chatgpt-bin 26.1013.40934-1, Arch/Omarchy, x86_64. These are observations from an existing profile, not a clean-profile reproduction.

    Two retained main-process runs on October 19, 2026, with times in America/Sao_Paulo (UTC−3):

    Observed interval Distinct failed request IDs Distinct chat IDs Queue wait median / maximum
    20:50:24.423–22:02:31.939 12,997 80 0 / 9 ms
    22:02:59.158–22:22:32.298 3,458 80 0 / 65 ms

    The same set of 80 chats recurs in both runs, totaling 16,455 distinct failed requests. Counts include rotated main-process logs and are deduplicated by request ID; corresponding response-routing records are not counted again. Every counted failure has:

    method=thread/read
    source=thread_hydration
    priority=background
    error.code=-32003
    error.message="thread access denied"
    

    This confirms repeated background denial in this Linux installation and persistence across two app runs. It does not establish the backend reason for the first denial, the caller of every request, sustained queue saturation, or the loop's CPU/memory cost. No failing wire payload or backend authorization decision was captured. The cause of separately reported desktop closures remains inconclusive; no causal link to hydration is asserted.

    Please bound repeated retries of explicit access denials until relevant access/identity changes or an explicit foreground retry, handle inaccessible entries independently, and provide a supported recovery path that preserves original chats and authorization boundaries. This adds platform/build evidence to the existing report; no separate issue is being opened.

    Privacy and scope: only aggregate measurements and generic error fields are included. No private chat/request/account identifiers, titles, conversation contents, personal filesystem paths, credentials, raw logs, screenshots, or attachments are included. This investigation did not restart applications or change installed code, profiles, caches, credentials, or shared configuration. Submitted with the user's authorization.

  11. idaibin commented on Oct 21, 2026

    @idaibin

    Additional macOS evidence, observed on October 21, 2026. This appears to match the recurring background-denial signature here; please consolidate with #53178 or #52129 if appropriate.

    Environment and scope

    • Installed desktop app verified as 26.1013.40934, build 20770, on Apple Silicon macOS.
    • Existing profile; no clean-profile reproduction.
    • Read-only analysis of retained application diagnostics, selected routing metadata, and the installed history-loading/scheduler implementation. No active task was interrupted and no diagnostic thread reads were replayed.

    Same targets recur during both subjectively stable and slow periods

    Two 30-minute windows on October 21, in UTC:

    Metric 00:26:14–00:56:14 05:35:03–06:05:03
    Matching denied-read failure log entries 1,470 936
    Distinct denied target IDs 78 78
    Background queue-full rejections 46 50
    Interactive queue-full rejections 0 39
    Maximum fs/getMetadata queue wait 13 ms 19,259 ms

    The denied target sets are identical. Each target has exactly 12 matching failure entries in the second window. Selection requires Request failed, method=thread/read, source=thread_hydration, priority=background, and -32003 / thread access denied. Corresponding response-routing rows are not counted again. Failure-entry counts are not counts of model turns or independently deduplicated request IDs.

    The user considered the first period more stable, but its logs were already abnormal. Activities differ, and a system boot occurred between the windows; this is not a controlled time-of-day or network comparison.

    Success and denial coexist for the same targets

    In the second window, 65 of the 78 targets also had successful thread/read responses: 66 successful responses for those 65 distinct targets. Success did not prevent subsequent background denial.

    Ownership checks were deliberately limited:

    • None of the 78 exact IDs matched the threads table in the local database confirmed open by the existing local app-server.
    • Client read/unread metadata placed 67 targets in a durable execution-host bucket. This is client metadata, not authoritative server ownership.
    • Existing per-request success/failure diagnostics do not record the destination host or threadAccess. The ordinary/shared difference reported elsewhere has not been isolated on these 78 targets.

    Thus, neither permanent loss of access nor “local threads incorrectly sent to cloud” has been established.

    Separate saturation episodes; causality is not assumed

    At 05:49 UTC, the interactive queue reached 64 with four requests in flight and initially zero queued background requests. There were 39 interactive queue-full rejections: 21 plugin/read, 13 fs/getMetadata, two thread/search, two fuzzy-search starts, and one metadata update. A file-metadata request waited 19,259 ms but took only 1 ms after dispatch. Successful plugin reads had a median queue wait of 13,023 ms.

    At 05:51 UTC, the background queue reached 128 with two requests in flight and zero queued interactive requests. All 50 background queue-full rejections involved the target set: 26 thread/turns/list and 24 thread/read. History responses had queue waits up to 37,031 ms.

    The denied-read loop is unnecessary background work, but it does not by itself explain the earlier interactive saturation. The 15 sampled turn/start responses in the second window waited at most 1 ms; this is not a model first-token or generation-speed measurement.

    Requested supported correction

    The installed durable-host hydratePinnedThreads implementation explicitly supplies threadAccess:"shared", consistent with the investigation here. Please investigate the successful versus denied access contexts, preserve the appropriate owner/shared semantics, and bound repeated denial retries per identity/host/target/access context. Reconcile individual failures without repeatedly reloading the entire retained target set. Please also investigate plugin-detail fan-out and protection of file/search request capacity separately unless a common mechanism is demonstrated.

    Please identify a supported client/service fix or a mitigation that preserves original chats and active work. No application bundle, credentials, authorization policy, database contents, cache, network/proxy settings, or running tasks were changed. No restart, downgrade, or installation was performed for this investigation.

    Only sanitized technical fields and aggregate measurements are included. Private target/request/account/device identifiers, conversation contents/titles, local paths, raw logs, and screenshots are omitted. Prepared and submitted by Codex at the user's explicit request.

  12. yongpengzheng95-ai commented on Oct 21, 2026

    @yongpengzheng95-ai

    Additional observation on macOS desktop build 21161 (2026-10-21)

    This appears to overlap the background hydration/direct-read discrepancy reported here.

    Environment

    • macOS 27.0.1.
    • Desktop app 26.1016.51333, build 21161, production channel.
    • Bundled app-server CLI 0.163.0-alpha.11.
    • The configured app updater reports no eligible update.

    These are existing-profile observations, not a clean-install reproduction.

    Observed after a full app restart

    • Background metadata reads repeatedly fail for the same nine conversation entries:
      • method: thread/read
      • source: thread_hydration
      • priority: background
      • error: -32003 / thread access denied
    • Through the supported normal read_thread path on the durable host, eight of those entries return metadata. Six also returned a recent turn; two returned no turns on the requested page. This is not a claim that all history has been verified.
    • One cached internal/dreaming entry could not be resolved by the durable host. This does not establish deletion or data loss.
    • Successful normal reads do not stop the repeated background denials. The desktop log also contains successful ordinary reads and subsequent turns/items requests for affected entries.

    Investigation limits
    Read-only inspection found differing access-context handling between explicit shared reads and general background hydration, plus rejected hydration memo entries being discarded after completion. Actual failing wire payloads and server authorization decisions were not captured. Therefore, a host-routing or access-context mismatch remains a hypothesis; we cannot identify the exact failing host or assert a missing shared field.

    Please investigate bounded handling of terminal denials and consistency between normal reads and background initialization. Please provide a supported recovery that preserves original conversations, login state, and authorization boundaries.

    Privacy
    This comment contains only version information, aggregate observations, and error/method names. No original report or evidence files, raw logs, screenshots, conversation IDs/titles/content, account or device identifiers, local paths, credentials, cookies, or session transcripts are attached or included. No chat database, ownership/access fields, credential store, or installed app package was modified during this investigation.

    Prepared and submitted by Codex with the user's explicit authorization.

  13. rkrisa commented on Oct 21, 2026

    @rkrisa

    Windows build 21161: cached hidden dreaming children enter the Orbit hydration set

    Additional read-only evidence from Windows on October 21, 2026, for this existing issue. Please consolidate with #51675 if appropriate.

    Environment: MSIX OpenAI.Codex 26.1016.6573.0; configured updater reports desktop 26.1016.51333, build 21161, production channel. These version fields are not interchangeable. Existing user profile; no clean-profile reproduction.

    Observed state and behavior

    • Eleven cloud references repeatedly receive -32003 / thread access denied from background thread/read with source=thread_hydration.
    • Same-day supported read_thread resolves eight of those references: five return a turn and three return metadata with no turns. Three others return the generic message Could not determine whether Codex thread ... exists. Unavailable or failed hosts: durable.
    • All three unresolved references are cached internal background threads with threadSource='dreaming' and attachment.is_user_visible=false, attached to one visible root. They are not three ordinary visible work chats. Their cached metadata names the same internal task type.
    • The retained cloud catalog's last successful refresh timestamp is October 7. Missing local SQLite/session records are consistent with cloud references and do not establish remote deletion.
    • Normal-read log errors for the three include -32600 / thread not loaded: [redacted] and Some requested entity was not found: thread not found. Background hydration logs for the same references instead contain -32003.
    • Successful normal reads did not establish that automatic hydration recovered; later denied background reads recurred. No claim is made that these errors explain all application slowdown.

    Installed-client control-flow findings

    1. The display-side visibility filter hides threadSource='dreaming'.
    2. The Orbit producer first selects eligible fresh attachments, then unconditionally unions all cached summary IDs. That cached branch does not apply the dreaming visibility rule, so hidden internal IDs can return to the hydration set.
    3. The producer calls hydratePinnedThreads(..., {throwOnReadError:true}) before committing its persistent catalog. A failed batch can prevent reconciliation and retain old candidates.
    4. This producer uses the durable host. It is not a demonstrated wrong-local-host route.
    5. Durable background hydration explicitly requests shared access. The main-process scheduling and serializer preserve that option and add params.threadAccess='shared' to the backend RPC. Normal tool metadata reads do not explicitly request that mode; loaded-conversation hints can also influence it. This proves a request-construction difference, not the actual wire payload or the server's authorization decision. It is premature to describe every successful normal read as owner mode or to switch access modes blindly.
    6. The public tool's host resolver first reads metadata and replaces individual failures with a boolean lookup-failed flag. Its not-found matcher does not accept every observed wrapped not-found message. A per-reference lookup failure can therefore be reported as a failed/unavailable host even while other references on that host remain readable.
    7. restoreCachedThreadSummaries returns already-suppressed archived IDs; it does not query the backend for missing references. Public archive goes through the same failing resolver before it can act. No supported live per-reference cache-prune operation was identified.

    Two isolated local checks of the shipped code branches reproduced the wrapped-message matcher gap and the explicit shared parameter serialization. They executed only synchronous code against synthetic metadata in a sandbox, with no network, application imports or IPC. They are not an installed fix or a capture of real wire traffic; no extracted source is attached here.

    Requested product fix / supported remediation

    • Reuse the native visibility policy when combining fresh and cached hydration candidates. Do not hydrate hidden dreaming children as ordinary human sidebar entries; preserve their source records rather than deleting history.
    • Preserve the legitimate authenticated access mode and transport for cloud metadata. Compare normal and explicitly shared requests for the same account and reference; do not weaken backend authorization or make private chats public.
    • Handle per-reference failures independently so available metadata commits, with bounded revalidation for denied/missing entries instead of failing and retrying the whole catalog.
    • Preserve structured code/cause/host information in public lookup errors. Do not call a healthy host unavailable merely because one reference cannot be resolved. Do not classify every generic -32600 as not-found.
    • Please provide either a supported server-side remediation compatible with the existing client, or a fixed client build plus a recovery procedure preserving history, drafts and active work. If a live scoped cache reconciliation is supported, document it rather than requiring app-data reset.

    Simply returning a canonical not-found for the three hidden references is insufficient in this build: the batch helper collects every read rejection when throwOnReadError=true and throws after the batch, without excluding missing-reference errors. A no-restart backend recovery would also require legitimate product catalog/archive reconciliation events and consistent attachment state so stale references are not reintroduced. Such a public operation has not been identified; this is a conditional request to the product owner, not a claimed available workaround.

    Acceptance should include the eleven-reference fixture, hidden-child exclusion, successful metadata refresh despite an individual denial, two actual refresh cycles, preserved references and drafts, and no unintended change in access permissions.

    No installed app, authentication state, feature gate, source database, conversation, automation or server permission was modified. No session was interrupted and no restart was used for this investigation. This comment contains no real thread/account/request IDs, private titles, personal paths, conversation contents, credentials, raw logs or extracted proprietary source. An independent review considered only a sanitized technical summary; it did not inspect or patch the running application.

  14. fortynova commented on Oct 22, 2026

    @fortynova

    Additional post-restart reproduction: Intel macOS, desktop 26.1016.51333 (21161)

    Adding a fresh reproduction to this existing issue rather than opening a duplicate. This case adds repeated access denial with an already-empty local sidebar thread/profile cache.

    Environment and observation boundary

    • ChatGPT-branded desktop app, bundle identifier com.openai.codex.
    • Current installed version: 26.1016.51333, build 21161.
    • macOS 14.6.1 (23G93), Intel iMac, x86_64.
    • Main application relaunched 2026-10-21 at 21:51:44 EDT; its new backend launched at 21:52:00 EDT.
    • Before relaunch the app was 26.1013.40934 (20770), so both the running session and app version changed. This was not a clean-profile installation test.

    Verified behavior after restart

    From 2026-10-22 01:52:09.260 UTC through 02:08:36.121 UTC (October 21, 21:52:09 through 22:08:36 EDT), the fresh app-session logs contain:

    • 722 failed thread/read requests across 19 distinct chat IDs.
    • Each of the 19 IDs appeared in 38 failed read requests in this window.
    • Consistent fields: JSON-RPC -32003, thread access denied, source=thread_hydration, priority=background.
    • Three Orbit catalog task metadata could not be loaded warnings were also observed in the same bounded window.
    • Twelve of the denied IDs match an earlier local support report from October 14. Their actual identifiers are deliberately not included here.

    Sanitized first and last failure records, shortened to the relevant fields:

    2026-10-22T01:52:09.260Z error [electron-message-handler] Request failed
    conversationId=<redacted-chat> durationMs=293
    error={"code":-32003,"message":"thread access denied"}
    method=thread/read priority=background queueWaitMs=0
    rendererWebContentsId=1 source=thread_hydration
    
    2026-10-22T02:08:36.121Z error [electron-message-handler] Request failed
    conversationId=<redacted-chat> durationMs=96
    error={"code":-32003,"message":"thread access denied"}
    method=thread/read priority=background queueWaitMs=0
    rendererWebContentsId=1 source=thread_hydration
    

    The placeholders do not assert that the first and last records refer to the same chat; counts above were calculated using the actual IDs locally.

    Local cache state and controls

    Read-only inspection of cloud-aeon-sidebar-cache-v1 under electron-persisted-atom-state in ~/.codex/.codex-global-state.json found:

    • profilesByThreadId: 0 entries.
    • threads: 0 entries.
    • attachments: 1 entry, preserved.

    No cached chat/profile entries were deleted during this post-restart check. The empty local thread/profile cache means another purge of those entries has no demonstrated target. It does not establish where every inaccessible reference originates; the current cloud catalog payloads and authorization decisions were not captured.

    An unrelated Fantastical MCP integration had been disabled before relaunch. The new session showed zero FantasticalMCP processes and zero Fantastical MCP startup events, while the sidebar denials continued. That is a useful separation from the independent MCP process buildup reported in #56026, not proof of the sidebar root cause.

    Impact and limits

    • The app continues repeating permanent-looking access failures after restart and update, producing unnecessary background requests and error-log traffic.
    • No actual HTTP 429 was found in this observation window. Arbitrary 429 substrings in timestamps and metadata were excluded.
    • Memory pressure was low; the new backend's physical footprint was about 436 MB at the later check.
    • CPU/GPU use was intermittent while two unrelated chats were actively working. Native samples caught substantial waiting time. These observations do not prove that the retry traffic caused the user's fan activity or all UI overhead.
    • The active chats were not interrupted. No credentials, permissions, cloud records, or app bundle files were modified.

    Requested investigation

    Please investigate why these inaccessible references continue to be hydrated when the persisted local sidebar thread/profile cache is empty. Treat access denial as a terminal unavailable state until identity/access changes or the user explicitly retries, and handle inaccessible entries independently so they do not continually fail and reload the catalog.

    This adds runtime evidence on the newer Intel/macOS build; the caller and error-classification code described in the original issue was not re-audited for this build. No raw logs, account identifiers, chat IDs/titles/content, private filesystem paths, or credentials are attached. Submitted with the user's authorization.

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 workingdotsIssues involving setting up ChatGPT dots or managing their ongoing work.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions