Skip to content

macOS: New Chat from Local Project creates a global chat instead of a project chat (cloud projects unaffected) #39489

Open

Description

@cmjones37

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

Version 26.814.41957

What subscription do you have?

Enterprise

What platform is your computer?

macOS (Tahoe 26.6.2)

What issue are you seeing?

Summary

New chats can no longer be created inside Local Projects in the macOS desktop app. Using the New Chat button on a local project creates a normal top-level chat instead of a project-scoped chat. The resulting chat has no access to the local project's context, knowledge sources, or agent skills.

The issue only affects Local Projects. Cloud-based projects on the same account behave correctly.

Project configuration

  • Project type: Local Project
  • Connected to an Obsidian vault (local folder)
  • Project contains existing chats and scheduled automations

What steps can reproduce the bug?

Steps to reproduce

  1. Create (or open) a Local Project connected to a local folder (e.g. an Obsidian vault).
  2. Hover over the project in the sidebar.
  3. Click the New Chat button.
  4. Observe where the new conversation is created.
  5. Ask the new chat a question that requires access to the project's files or agent skills.

What is the expected behavior?

Expected result

  • A new chat is created inside the Local Project.
  • The chat inherits the project's context.
  • The chat can search the connected Obsidian vault.
  • The chat has access to the project's configured agent skills.
  • The chat appears under the Local Project in the sidebar.

Actual result

  • A normal top-level chat is created in the general chat list.
  • The chat is not associated with the Local Project.
  • The chat behaves as though the project does not exist.
  • It cannot search the connected vault.
  • It has no access to the project's agent skills.
  • There is no way to move the chat into the Local Project afterwards.

Additional information

Additional observations

  • Existing chats that were previously created inside the Local Project remain present and continue to function.
  • Scheduled automations attached to the Local Project continue to run successfully, including reading from and writing to the connected Obsidian vault.
  • This suggests the Local Project itself and its indexing are still functioning, but new interactive chats are not being bound to the project.
  • Clicking the project name only expands/collapses the sidebar section; there is no project view that can be opened.
  • Right-clicking the project shows expected options such as Settings and Pin, but there is no alternative way to create a project-scoped chat.

Comparison with Cloud Projects

Cloud Projects on the same account behave as expected:

  • Hovering over a Cloud Project and clicking New Chat creates a project-scoped chat.
  • The chat inherits the project's context.
  • Chats can still be moved into Cloud Projects via drag-and-drop or the Move to Project action.

The issue appears to be specific to Local Projects in the macOS desktop application.

Additional troubleshooting performed

  • Created a brand new Local Project using a separate test folder.
    • Same behaviour.
  • Verified that the issue reproduces across multiple Local Projects.
  • Restarted the desktop app.
    • No change.
  • Attempted to drag a chat into the Local Project.
    • Not possible.
  • Checked the chat context menu.
    • Move to Project is available for Cloud Projects but not for Local Projects.
  • Verified that project automations continue to function.
    • Confirms the Local Project itself is still operational.

Impact

This prevents using Local Projects interactively. Although automations continue to function, it is no longer possible to start a conversation that has access to the project's local knowledge sources or agent skills.

Notes

This appears to be a regression affecting the binding between newly created chats and Local Projects rather than an issue with the Local Project, indexing, or connected files themselves.

Activity

  1. added
    appIssues related to the Codex desktop app
    on Aug 19, 2026
  2. added
    bugSomething isn't working
    sessionIssues involving session (thread) management, resuming, forking, naming, archiving
    on Aug 19, 2026
  3. liulili-ui commented on Aug 24, 2026

    @liulili-ui

    Windows reproduction confirmed.

    Environment

    • Platform: Windows
    • Codex Desktop package: 26.818.5229.0
    • Internal release shown in the desktop logs: 26.818.41509

    Reproduction

    1. Open a saved Local Project.
    2. Click the New Chat button on the right side of that project in the sidebar.
    3. Send a message in the newly created chat.

    Actual result

    The chat is created as a normal global/cloud ChatGPT conversation instead of a local project-scoped Codex task. The local thread catalog records the failed chat with:

    • source_kind = chatgpt
    • cwd = null
    • project_id = null
    • conversation_origin = null

    The desktop log shows the creation route as:

    client-new-thread -> local-chatgpt -> /work/conversation

    There is no local thread/start call for the failed creation.

    Expected result

    A chat created from the Local Project's own New Chat button should inherit that project and its local workspace.

    Existing local project chats still work correctly, and the problem reproduces across multiple Local Projects. This started after updating Codex Desktop, so this appears to be the same project-binding regression reported here, also affecting Windows.

    I can provide sanitized thread metadata or the relevant desktop log excerpt privately if maintainers need it.

  4. zchengb commented on Sep 14, 2026

    @zchengb

    macOS reproduction confirmed, with an additional Local Project picker symptom.

    Environment

    • Platform: macOS (Apple Silicon)
    • Codex Desktop: 26.903.61454
    • Project setup: 4 Local Projects + 2 Cloud Projects

    Reproduction

    1. In the sidebar, click New Chat next to an existing Local Project.
    2. Send a message in the new chat.
    3. Observe where the chat appears.

    Actual result

    • The newly created chat appears under Recents only.
    • It does not appear under the Local Project from which it was created.
    • Existing chats that were already associated with the Local Project remain visible under that project.
    • Cloud Projects do not show the same problem.

    Additional symptom

    The Work in a project picker also does not list all Local Projects:

    • All 4 Local Projects are visible in the Projects sidebar.
    • Both Cloud Projects are visible in the picker.
    • Only 1 of the 4 Local Projects is visible in the Work in a project picker.

    This makes it look like the Local Projects themselves still exist, but some project/session association or registration used by new Chat/Work entry points is not being recognized correctly.

    No project names, local paths, files, account identifiers, or private content are included here.

  5. zchengb commented on Sep 14, 2026

    @zchengb

    Duplicate comment posted in error — please disregard. The reproduction details are in the immediately preceding comment.

  6. zchengb commented on Sep 14, 2026

    @zchengb

    Duplicate comment posted in error — please disregard. The reproduction details are in the earlier macOS reproduction comment.

  7. bpuckett74 commented on Sep 28, 2026

    @bpuckett74

    Additional macOS reproduction and follow-up (September 28, 2026 UTC).

    Environment: ChatGPT/Codex desktop 26.924.22138 (build 11645), bundled app-server 0.158.0-alpha.2.1.

    The user reports clicking New Chat from an existing saved Local Project in the sidebar. The resulting chat is a local Codex thread whose recorded working directory matches the project's primary folder, but the desktop list_threads readback reports projectId: null and places it in general Tasks. The saved project remains registered; 18 other active Codex chats in the same listing have its correct ID, including a subsequently created chat.

    The user also tested the documented /project selector: selected the same Local Project for a new chat and sent a test message. That second chat likewise has the correct working directory but projectId: null in list_threads. Thus /project is not a workaround in this environment.

    Read-only local-state inspection adds a narrower discrepancy: Desktop's persisted thread-project-assignments maps contain the correct saved project ID for both failed chats, with local host membership and neither marked projectless. Yet the desktop chat listing returns null for both. The app-server threads.project_id is null for these chats, but also for a chat that Desktop correctly lists under the project, so that column alone does not explain the difference. A thread/start for the first failed chat completed without a logged error; available logs do not expose the project-binding input or identify the failing component.

    This points to inconsistent project membership resolution across desktop/app-server state. It does not prove a specific code path or update caused the regression. Project/thread IDs, the local path, and chat contents are omitted from this public comment.

  8. Yourmomsfitnesstrainer commented on Oct 1, 2026

    @Yourmomsfitnesstrainer

    Additional macOS reproduction on October 1, 2026, with a Git branch visibility symptom.

    The user reports repeatedly starting tasks from inside an existing saved Local Project. For the current task, I checked the desktop's read-only project and thread listings and the repository's Git state:

    list_projects: saved Local Project, projectId=<non-null UUID>, isGitRepository=true, path=<repo>
    list_threads:  current local Codex task, projectId=null, cwd=<same repo>
    sidebar:       task listed under general Tasks, not under the saved project
    git branch --show-current: <existing named branch>
    

    Other Codex tasks with this same repository as their working directory do report the saved project's non-null ID, so the project registration is present. The current task can access the checkout and Git confirms that the branch exists, but the branch is not shown for this task in the desktop UI. The user reports that this mismatch recurs when starting tasks inside projects.

    Expected: a task started from a saved Local Project retains that project's ID, appears in the project, and shows the active Git branch. Actual: this task has the correct working directory but projectId: null, appears in general Tasks, and does not show the branch.

    I did not test whether restarting the app repairs this task. I am not asserting which component dropped the association. Project name, absolute path, project/thread IDs, branch name, and repository content are omitted from this public report.

  9. Yourmomsfitnesstrainer commented on Oct 1, 2026

    @Yourmomsfitnesstrainer

    Follow-up with a partial local workaround tested on macOS (October 1, 2026). I installed user-level Codex hooks that attach a missing backend Project ID to new local Codex tasks when their working directory matches a registered Local Project. This does not repair the desktop sidebar/cache: for the current task, the backend assignment is verified, while the live desktop list_threads result still says projectId: null and lists it under general Tasks. Please do not treat this as a fix for the UI or Git branch display.

    Hook wiring

    I added command handlers to ~/.codex/hooks.json (merging them with existing handlers, not replacing them):

    {
      "hooks": {
        "SessionStart": [{
          "matcher": "^(startup|resume)$",
          "hooks": [{"type": "command", "command": "/usr/bin/python3 /ABSOLUTE/PATH/project-binding/launcher.py 2>/dev/null || true", "timeout": 15, "additionalContextLimit": 2000}]
        }],
        "UserPromptSubmit": [{
          "hooks": [{"type": "command", "command": "/usr/bin/python3 /ABSOLUTE/PATH/project-binding/launcher.py 2>/dev/null || true", "timeout": 15, "additionalContextLimit": 2000}]
        }],
        "PreToolUse": [{
          "hooks": [{"type": "command", "command": "/usr/bin/python3 /ABSOLUTE/PATH/project-binding/launcher.py 2>/dev/null || true", "timeout": 15}]
        }]
      }
    }

    The three events all call the same idempotent worker. SessionStart can fire before a new thread is persisted, so UserPromptSubmit and PreToolUse provide bounded later chances. Review/trust the hooks through Codex's normal hook approval flow. The placeholder path must be replaced with an absolute path to a local script. See the official hooks documentation for event and output formats.

    What the worker does

    1. Read the hook's session_id (or CODEX_THREAD_ID) and validate it. Open the newest ~/.codex/state_*.sqlite read-only. Query SELECT * FROM threads WHERE id=? and SELECT p.id,p.name,r.path FROM projects p JOIN project_roots r ON p.id=r.project_id. Never write to SQLite or the desktop global-state JSON.

    2. Stop if the task predates installation, is a subagent, already has threads.project_id, or has an explicit desktop assignment that cannot be matched safely. Resolve the task's recorded cwd against registered project roots; use the deepest unambiguous root. For linked Git worktrees, project the worktree path back to the main checkout's registered root. If there is no unique match, do nothing.

    3. Immediately before mutation, re-read the thread and project/desktop assignment. If the working directory, project catalog, or assignment changed, do nothing. For the matching task, start a short-lived codex app-server --stdio process with hooks disabled in that child (-c features.hooks=false) to avoid recursion, and point sqlite_home at the same state directory. Send initialize and initialized on its JSON-RPC stdin, then call the internal method:

      {"id": 2, "method": "thread/metadata/update", "params": {"threadId": "<thread-id>", "projectId": "<registered backend project id>"}}
    4. Require the RPC response to contain that Project ID, then verify it with a fresh read-only SQLite snapshot. Only after both checks does the hook emit model context saying which project was matched. It explicitly says the desktop UI is unverified. A per-thread journal and file lock prevent repeat writes. The launcher has a 12-second worker deadline, always exits successfully so normal work continues, and temporarily disables itself after three consecutive failures. A DISABLED marker and removal of only these hook handlers provide a reversible off switch.

    My implementation also compares any desktop-side thread-project-assignments in ~/.codex/.codex-global-state.json read-only so it will not overwrite an explicit user choice. It stores only small status/error codes locally; no prompts, transcripts, tokens, or raw API errors. I backed up the prior hook config before installing and added an agent instruction to use the verified backend metadata as project context when desktop still reports null.

    This is a version-sensitive workaround, not a supported Project API: it depends on local SQLite table names and an internal app-server method. A different Codex release may need adaptation. The remaining discrepancy in this reproduction is precisely that a confirmed backend Project ID does not make the desktop's live project listing recognize this task.

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 appbugSomething isn't workingsessionIssues involving session (thread) management, resuming, forking, naming, archiving

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions