Skip to content

[macOS] Durable dot activity missing from local project despite saved assignment; background reads return -32003 #53326

Open

Description

@BryanYue

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

Installed macOS desktop bundle: 26.1007.30912, build 20156, bundle ID com.openai.codex.

Version was read from installed bundle metadata, not independently confirmed from the running window's About dialog. Observations: 2026-10-12.

What subscription do you have?

Not included in this public report; not independently verified during this privacy-limited investigation.

What platform is your computer?

macOS on Apple Silicon. Read-only command outputs:

sw_vers -productVersion: 26.6.2
uname -mprs: Darwin 25.6.0 arm64 arm

What issue are you seeing?

Activities created through a dot can be found in Recent activity and by the supported list_threads tool, but do not appear under their intended existing local folder project in the desktop sidebar. Some carry a Cloud label.

For the primary affected activity, the local saved project assignment is already present and correct. Nevertheless, the supported list returns hostId="durable" and projectId=null. This is a discoverability/project-grouping inconsistency, not a claim of lost history.

The original activity remains identifiable, and existing logs contain successful history reads as well as repeated background metadata-read denials for that same ID. Local control chats remain associated with their projects.

Please distinguish these four facts when investigating:

  1. Conversation storage/source and routing identity, including durable.
  2. The computer/environment that actually executes a turn.
  3. Working directory.
  4. Saved project membership versus the project grouping exposed by the list/sidebar.

A Cloud badge or hostId="durable" alone does not establish the physical execution machine. No per-turn execution-location claim is made here.

What steps can reproduce the bug?

Observed workflow on an existing account/state; a clean-profile or deterministic fresh-creation reproducer has not been established. No new test chat was created during diagnosis.

  1. Have an existing local folder project, anonymized here as Project A, with an accessible local working directory.
  2. Ask a dot to create a separate activity intended for Project A. The recorded creation context states that Project A's project ID was supplied, and the resulting activity's working directory matches that project's root. The original raw creation request was not independently re-captured.
  3. Find the resulting original activity in Recent activity; its history remains available.
  4. Expand Project A in the local-project sidebar. The activity is absent even though the project itself exists. The owner reports that leaving/changing the recent-activity view does not make it appear under Project A.
  5. Inspect the existing activity through the supported project/thread listing tools: Project A is returned as a local project, while the activity is returned as kind="codex", hostId="durable", projectId=null.
  6. Inspect only the corresponding saved app-state metadata, read-only: the same activity already has a local Project A assignment and is not explicitly projectless.
  7. Compare a normal local chat: the supported list resolves its project normally. Inspect existing logs for the affected activity: background thread/read failures coexist with successful reads.

Steps 1–4 describe the existing workflow/user observations. Steps 5–7 are the read-only diagnostic checks. UI automation and a controlled creation/restart test were not performed.

What is the expected behavior?

An activity explicitly assigned to a local project should be discoverable under that project, or the product should explain an unsupported association/access prerequisite instead of silently returning a null grouping.

If recovery is needed, please provide a supported, single-activity reassociation/reload/reindex operation with a documented rollback that:

  • preserves the original activity ID, messages, history and links;
  • makes that original activity visible under its intended local project;
  • leaves normal local chats and other project memberships unchanged;
  • does not change execution host/environment or working directory;
  • does not restart or reopen closed Goals.

A replacement chat or a Cloud badge change would not satisfy this recovery requirement.

Additional information

Primary correlation ID and sanitized metadata

Original affected activity ID (intentionally retained for maintainers' correlation):

01a12960-1198-7172-8ca9-8078211120d1

Project names, project IDs, titles and actual directory paths are redacted. <LOCAL_PROJECT_A> below is a placeholder, not a real ID.

Supported list result, selected fields:

{
  "id": "01a12960-1198-7172-8ca9-8078211120d1",
  "kind": "codex",
  "hostId": "durable",
  "projectId": null
}

Corresponding selected fields from $CODEX_HOME/.codex-global-state.json:

{
  "thread-project-assignments": {
    "01a12960-1198-7172-8ca9-8078211120d1": {
      "projectKind": "local",
      "projectId": "<LOCAL_PROJECT_A>"
    }
  },
  "thread-project-membership-host-ids": {
    "01a12960-1198-7172-8ca9-8078211120d1": "durable"
  }
}

The affected ID is not in projectless-thread-ids. The saved local-project definition exists and its root matches the activity's recorded working directory. Normal local controls have corresponding saved assignments and "local" membership hosts.

In one inspected snapshot, all 35 durable entries had projectId=null, while normal local controls returned project associations. This is an observational sample, not proof that all durable activities are affected or that the problem is exclusive to dot-created activities.

Raw SQLite project_id is also null for some correctly grouped local control chats. Consequently, a null database field alone is not proof of missing membership, and no database rewrite was attempted.

Selected existing log fields

The snippets below are field selections from existing logs, not complete raw log lines. They are all for the primary affected activity above.

Failure example:

requestId/id=c0514f5c-d283-4e66-b625-873acb5b6e84
method=thread/read
source=thread_hydration
priority=background
timeoutMs=0
error={"code":-32003,"message":"thread access denied"}
failureReason=null
traceId=null
spanId=null

An earlier failure has the same signature:

requestId/id=6a41f72e-1197-4021-81f6-6bb14f206705
method=thread/read
errorCode=-32003

Successful response for the same activity:

requestId=b0ba8f3d-d07a-4391-93cc-39c029054bc8
method=thread/read
errorCode=null
durationMs=366

An earlier diagnostic snapshot contained 224 failed thread/read request IDs with this denial, 6 successful thread/read responses, 4 successful thread/turns/list responses, and 1 successful thread/items/list response for this activity. A later snapshot reached 228 denial records. These are log/request counts, not unique activities or model turns. No failed read was deliberately retried by the diagnostic investigation.

The inspected text logs do not record the failed requests' actual connection host or final effective threadAccess, and their trace/span IDs are null. The successful and failed paths therefore cannot be declared equivalent. The absence of these logged fields is not evidence that the outgoing requests omitted them.

Client-side investigation leads — not a confirmed root cause

Read-only inspection of the installed client suggests:

  • The projectId exposed by list_threads is derived from assembled sidebar project groups, rather than directly returning the saved assignment above. Thus a null list result does not prove that the saved assignment is absent.
  • A local project's additional durable materialization scope depends on feature gate 375130565 and effective runtime cloudAccess. The gate's actual runtime value and effective access value were not obtained.
  • This additional scope uses explicit activity inclusion rather than cwd matching; the loader also depends on its available/registered host set.
  • The durable recent-history path has an originators: ["codex_cloud"] filter, whereas the inspected supported list_threads path does not. The primary activity's actual originator was not independently established.
  • The inspected cloud-aeon-sidebar-cache-v1 did not contain the affected activity. Its absence is an observation, not proof of the cause.
  • Existing disk logs omit host/access details needed to compare failed hydration with successful reads. An in-memory request recorder exists, but it requires a diagnostic subscriber; it cannot reconstruct historical requests, and final transport-level access handling still needs verification.

Please correlate the supplied IDs and inspect:

  1. Effective gate/access values and whether Project A's durable loading scope was actually scheduled.
  2. The loader's actual host set and saved-assignment-to-sidebar reconciliation.
  3. The failed versus successful requests' actual host, transport, final threadAccess and authorization context.

These leads do not establish creation-time membership loss, actual cloud execution, a specific misconfigured local profile, or a uniquely identified authorization defect.

Related reports checked

The symptoms overlap; a shared root cause has not been established. Please consolidate if appropriate.

Privacy and investigation boundaries

Only one activity ID and selected request correlation IDs are retained intentionally. Actual project names/IDs, local paths, chat titles, account/workspace identifiers, private repository details, prompts, conversation bodies and attachments are omitted. No screenshots, raw logs, databases, full configuration files, credentials, authentication files or keychain data are attached.

Diagnosis did not modify databases or app state, merge configuration roots, migrate history, switch accounts, restart the app, create replacement chats, force hidden feature gates, bypass an access denial, or reopen closed Goals.

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 12, 2026
  2. whois-rb commented on Oct 17, 2026

    @whois-rb

    Additional corroborating macOS observation from October 17, 2026.

    Environment: Installed ChatGPT desktop version 26.1013.40934, build 20770, read from the app bundle metadata.

    We asked Dot to create local Codex tasks in an existing local folder project, selected by name. Dot reported supplying the project ID and matching working directory.

    Verified observations

    • Two Dot-created tasks successfully returned an initial acknowledgment and a second acknowledgment after a follow-up to the same task. Native desktop read_thread independently verified both completed turns for one task.
    • Both tasks were absent from the intended project’s sidebar group.
    • Native list_threads returned hostId="durable" and projectId=null for both, with the expected working directory.
    • Read-only inspection of .codex-global-state.json found explicit assignments to the intended local project in thread-project-assignments, with durable recorded in thread-project-membership-host-ids. Neither task was in projectless-thread-ids.
    • A supported move_thread_to_project attempt for one task returned:
      The project move was cancelled, unsupported, or failed.
    • Subsequent listing still returned null project membership.

    The saved-state inspection happened after the move attempt, so this does not independently establish when that assignment was persisted.

    Background reads versus direct reads

    Existing desktop logs contain repeated failures for these same tasks:

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

    Direct native history reads nevertheless succeeded.

    Client-side investigation lead

    Read-only inspection of the installed bundle found that project-move classification treats non-local host identifiers as remote. The move handler rejects a destination project-kind mismatch when the task is not already included in the destination’s displayed group. This appears consistent with the observed durable → local-project rejection; it is a code-based inference, not a captured runtime branch trace.

    We have not independently established the tasks’ physical execution location, the original raw creation arguments, or the underlying reason for the background read denials.

    Please investigate reconciliation between saved project assignments, durable-host sidebar loading, and move eligibility. A supported recovery should preserve the existing task IDs and history.

    No configuration, database, permissions, or app-code edits were made. Private task/project IDs, computer names, paths, conversation contents, and raw logs are omitted.

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