Codex app associates old merged PR with every chat on the default branch

Open 💬 1 comment Opened Jul 23, 2026 by finament-solutions

What version of the Codex App are you using?

See the diagnostic bundle associated with Feedback ID 019f9110-5e85-73a2-85fd-afe8c0c819b8.

What subscription do you have?

See the diagnostic bundle associated with Feedback ID 019f9110-5e85-73a2-85fd-afe8c0c819b8.

What platform is your computer?

Windows x64.

What issue are you seeing?

When a local project is checked out on its default branch, the Codex app can display a violet pull-request badge and PR context for an unrelated, historical PR that has already been merged and closed. The stale association appears in the sidebar or environment header for every unrelated chat that shares that local project environment, even though no open PR exists for the checked-out branch and the chats do not reference the old PR.

This appears to be a branch-resolution bug. If a repository has any historical PR whose head was the repository's default branch—for example, a reverse-direction synchronization PR from the default branch into a feature branch—the app may treat that merged PR as the current PR indefinitely whenever the local checkout is on the default branch.

This makes unrelated chats look connected to obsolete work and can surface irrelevant PR or review context.

What steps can reproduce the bug?

  1. Use a GitHub repository with a default branch such as main or master.
  2. Ensure the repository has a historical PR where the default branch was the PR's head and another branch was its base.
  3. Merge or close that historical PR.
  4. Check out the default branch locally and confirm that it has no open PR.
  5. Open the local repository as a project in the Codex app.
  6. Create or open several unrelated chats that use the shared local project environment.
  7. Observe that the app displays PR context for the historical merged/closed PR across those chats.

Feedback ID: 019f9110-5e85-73a2-85fd-afe8c0c819b8

What is the expected behavior?

The app should display PR context only for a relevant open PR whose head matches the checked-out branch. Closed or merged PRs should not be treated as the current PR. If several historical PRs share the same head branch name, open PRs should be prioritized and closed/merged matches ignored. When the checked-out branch has no open PR, no PR badge or PR context should be shown.

Additional information

The repository-specific example has intentionally been omitted because the affected repository and its branches are private. The feedback bundle should contain the app diagnostics needed to identify the affected session without exposing project data.

View original on GitHub ↗

1 Comment

Colin-Bao · 26 days ago

I ran into the same issue with Codex Desktop showing a historical merged PR as associated with new sessions on the current branch.

I traced this to the PR lookup using gh pr list with --state all. This allows merged and closed PRs to be returned, after which Codex may select one of them as the current PR.

As a temporary workaround, I placed the following narrow wrapper earlier in PATH. The repository and branch values below are placeholders:

#!/usr/bin/env bash
set -euo pipefail

REAL_GH=/usr/bin/gh
TARGET_REPO="OWNER/REPO"
TARGET_HEAD="BRANCH"

args=("$@")
is_pr_list=false
matches_repo=false
matches_author=false
matches_head=false
state_index=-1

if [[ ${args[0]-} == pr && ${args[1]-} == list ]]; then
  is_pr_list=true
fi

for ((i = 0; i < ${#args[@]}; i++)); do
  case ${args[i]} in
    --repo)
      [[ ${args[i + 1]-} == "$TARGET_REPO" ]] && matches_repo=true
      ;;
    --repo=*)
      [[ ${args[i]#--repo=} == "$TARGET_REPO" ]] && matches_repo=true
      ;;
    --author)
      [[ ${args[i + 1]-} == @me ]] && matches_author=true
      ;;
    --author=@me)
      matches_author=true
      ;;
    --head)
      [[ ${args[i + 1]-} == "$TARGET_HEAD" ]] && matches_head=true
      ;;
    --head=*)
      [[ ${args[i]#--head=} == "$TARGET_HEAD" ]] && matches_head=true
      ;;
    --state)
      [[ ${args[i + 1]-} == all ]] && state_index=$((i + 1))
      ;;
    --state=all)
      state_index=$i
      ;;
  esac
done

if [[ $is_pr_list == true &&
      $matches_repo == true &&
      $matches_author == true &&
      $matches_head == true &&
      $state_index -ge 0 ]]; then
  if [[ ${args[state_index]} == --state=all ]]; then
    args[state_index]=--state=open
  else
    args[state_index]=open
  fi
fi

exec "$REAL_GH" "${args[@]}"

This changes --state all to --state open only for the specific PR lookup used by Codex. All other gh invocations are passed through unchanged.

After restarting Codex, the stale PR association disappeared. This seems to confirm that the lookup should either query only open PRs or filter out merged/closed PRs before selecting the associated PR.

I’ll remove this local workaround once the upstream fix is available.