Skip to content

[Bug]: Work on PR loses its worktree and branch when switching environments on mobile #27616

Closed

Description

@Pratham-commits-code

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/mobile

Steps to reproduce

  1. On mobile, connect two environments that both have the same repository as a project (here: app-brew/gauntlet on "Pratham's MacBook Pro" and on "pratham").
  2. Open a pull request (Steer: say why a message queued instead of steering #20839) and tap Work on PR.
  3. The new-thread draft opens on the MacBook Pro environment with New worktree · From PR Steer: say why a message queued instead of steering #20839 and the #20839 chip in the composer. This is correct.
  4. Tap on Pratham's MacBook Pro and switch the environment to pratham.
  5. Switch the environment back to Pratham's MacBook Pro.

Expected behavior

The draft keeps the PR context on every environment:

Actual behavior

  • After switching to pratham, the composer still shows the #20839 chip, but the workspace row changes to Current checkout · rn81/android (that machine's current branch). The PR worktree setup is gone.
  • After switching back to Pratham's MacBook Pro, the row shows Current checkout · Choose branch. The new-worktree mode and PR branch from step 3 are lost, so the user has to set up the PR checkout again by hand.

The composer chip says the thread is about PR #20839 while the workspace selection no longer matches it. Sending from this state would run on the wrong checkout.

Impact

Major degradation or frequent failure

Version or commit

main @ b883fc0

Environment

iOS (T3 Code Mobile), two connected environments (macOS desktop host and a second remote host)

Notes for investigation

  • The new-task draft is keyed per project: new-task:${environmentId}:${projectId} (apps/mobile/src/features/threads/new-task-flow-provider.tsx, selectedProjectDraftKey). selectEnvironment only swaps the selected project. The PR's workspaceSelection (worktree mode plus PR branch) is not carried over to the matching project on the target environment, but the composer's PR context is.
  • Switching back does not restore the original selection either. One possible cause: selectEnvironment re-matches a project by repository identity, then workspace basename, then title. If the machine has more than one project for the repo, it may land on a different project/draft key than the one Work on PR used. Another possible cause: something resets the original draft's workspaceSelection while the user is on the other environment. This is not confirmed.

Screenshots, recordings, or supporting files

trim.EC1D07A4-1966-42AB-8018-43D1FBA95C20.MOV

Activity

  1. Pratham-commits-code commented on Oct 30, 2026

    @Pratham-commits-code
    Author

    Triage diagnosis

    Checked against main @ 6575ce3. This corrects the guess in the original report: the cause is not the wrong project being matched.

    Root cause

    1. Work on PR creates one new-task draft and stores a PR-specific workspaceSelection on it: { mode: "worktree", branch: pr.headBranch, worktreePath: null, startFromOrigin: false, pullRequestReference: pr.url } (apps/mobile/src/features/pull-requests/usePullRequestThreads.ts, ask).
    2. Switching environment calls selectEnvironment, then carryDraftContentTo(match), then retargetNewTaskDraft(draftKey, target) (apps/mobile/src/features/threads/new-task-flow-provider.tsx).
    3. retargetNewTaskDraft deliberately strips workspaceSelection when it moves the draft (apps/mobile/src/state/use-composer-drafts.ts, const { workspaceSelection: _workspaceSelection, ...retained } = normalizeDraft(existing)). Text, context records, attachments, and runtime mode are kept. That is why the #20839 chip survives while the worktree and PR branch do not.
    4. Switching back goes through the same retarget. The selection was already deleted on the first move, so nothing can be restored and the draft shows Current checkout · Choose branch.

    The strip was added on purpose in #10327 ("allow several new-task drafts per project"). use-composer-drafts.test.ts asserts moved.workspaceSelection is undefined after a retarget. That is right for ordinary drafts, because a branch or worktree path on one machine means nothing on another. A PR-backed selection is different: mode: "worktree", the head branch, and pullRequestReference are repository-level, not machine-level, so they are valid on any environment that has the same repository.

    Suggested fix

    In retargetNewTaskDraft, keep workspaceSelection when it carries a pullRequestReference, resetting only worktreePath to null. Update the existing retarget test, and add a case where a PR-backed draft keeps its selection across a move and a move back.

    Scope note: this is mobile-only as diagnosed. The web new-thread draft's environment switch was not checked and may need the same decision.

    Related


    Triage by Claude Opus 5.5 (Claude Code), following the t3 triage playbook.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions