Skip to content

Keep stable shell paths in detection and recover stale shell preferences - #15837

Open
thiagohflima wants to merge 1 commit into
warpdotdev:masterfrom
thiagohflima:thiagohflima/fix-homebrew-shell-preference
Open

Keep stable shell paths in detection and recover stale shell preferences#15837
thiagohflima wants to merge 1 commit into
warpdotdev:masterfrom
thiagohflima:thiagohflima/fix-homebrew-shell-preference

Conversation

@thiagohflima

Copy link
Copy Markdown

Description

Fixes #15836.

On macOS, selecting a Homebrew-installed shell (e.g. fish) as the default shell for new sessions silently reverted to the system default (zsh) after every brew upgrade of the shell.

Root cause: shell detection canonicalized /opt/homebrew/bin/<shell> to the versioned Cellar path (dunce::canonicalize in resolve_all_executables / load_fallback_shells), and that versioned path was persisted as the NewSessionShell::Executable preference. A formula upgrade removes the old Cellar directory, so the exact-path match against re-detected shells failed and get_user_preferred_shell silently fell back to SystemDefault.

This PR implements the direction suggested in the issue's triage:

  • Detection keeps the discovered (symlink-stable) path for storage and launch; the canonical path is used only as the dedupe key in resolve_all_executables and load_fallback_shells. New preferences persist /opt/homebrew/bin/fish, which survives upgrades.
  • get_user_preferred_shell recovers preferences that no longer exact-match a detected shell instead of silently resetting: an existing path is matched by canonical target (covers preferences persisted by older builds, i.e. the rollout transition), and a removed path resolves to the detected known shell of the same type, preferring the install closest to the stale path (multi-install machines).
  • Session restore (get_from_shell_launch_data) applies the same recovery to stale snapshot paths before falling back to a custom shell, so restored workspaces also survive an upgrade that happened while Warp was closed.
  • Deliberate out-of-catalog executables (existing file matching no detected shell) are unchanged: they still launch via the existing fallback paths.

No UI changes.

Linked Issue

Fixes #15836

  • The linked issue is labeled ready-to-spec or ready-to-implement. — filed by this PR's author with a full root-cause analysis and repo-validated repro (repro:high, deemed eligible for auto-implementation); per the "PRs opened without a linked issue" guidance, this PR links it for maintainer readiness review.
  • Where appropriate, screenshots or a short video of the implementation are included below (especially for user-visible or UI changes). — not applicable; no UI changes.

Testing

Automated (new regression tests in app/src/terminal/available_shells_tests.rs, all hermetic via VirtualFS):

  • test_keeps_stable_symlink_path_for_homebrew_shells — detection stores the stable bin/fish symlink, not the Cellar path, in a simulated Homebrew layout.
  • test_recovers_executable_preference_via_canonical_alias — a preference persisted as an old Cellar path still matches while the file exists (Warp-update transition).
  • test_recovers_stale_executable_preference_by_shell_type — a removed Cellar path recovers to the detected fish.
  • test_recovery_prefers_the_closest_install_prefix — multi-install machines pick the install closest to the stale path.
  • test_does_not_recover_existing_unmatched_or_non_shell_preference — out-of-catalog executables keep prior behavior.
  • test_get_from_shell_launch_data_recovers_stale_snapshot_path — session restore recovers stale snapshot paths; existing unknown paths still restore as custom shells.
  • test_dedupe_symlinks_when_discovering_paths — updated to document that dedupe keys are canonical while stored paths remain the discovered ones.

I don't have a Rust toolchain on this machine, so I lean on CI for ./script/presubmit (fmt/clippy/nextest); I verified the change by close reading and self-review only. Happy to push follow-ups if CI flags nits.

  • I have manually tested my changes locally with ./script/run — unable to build locally (no toolchain); the change alters shell resolution logic only and is covered by the tests above, but I understand if a manual ./script/run pass is needed and can arrange one on request.

Screenshots / Videos

Not applicable — no user-visible UI change.

Agent Mode

  • Warp Agent Mode - This PR was created via Warp's AI Agent Mode

CHANGELOG-BUG-FIX: Fixed the default shell preference silently resetting to the system default shell after a Homebrew upgrade of the shell.

Shell detection canonicalized /opt/homebrew/bin/<shell> to the versioned
Homebrew Cellar path, and that path was persisted as the new-session shell
preference. A formula upgrade removes the old Cellar directory, so the exact
path match against re-detected shells failed and the preference silently fell
back to the system default shell.

Detection now keeps the discovered (symlink-stable) path for storage and
launch, using the canonical path only as the dedupe key. Preferences that no
longer match a detected shell recover instead of resetting to the default:
an existing path is matched by canonical target (covering preferences
persisted by older builds), and a vanished path resolves to the detected
known shell of the same type, preferring the install closest to the stale
path. Session restore applies the same recovery to stale snapshot paths
before falling back to a custom shell.

Fixes warpdotdev#15836
@cla-bot

cla-bot Bot commented Sep 5, 2026

Copy link
Copy Markdown

Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have the users @thiagohflima on file. In order for us to review and merge your code, each contributor must visit https://cla.warp.dev to read and agree to our CLA. Once you have done so, please comment @cla-bot check to trigger another check.

@github-actions github-actions Bot added the external-contributor Indicates that a PR has been opened by someone outside the Warp team. label Sep 5, 2026
@warp-for-oss

warp-for-oss Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

@thiagohflima

Every PR must be linked to a same-repo issue before Oz can review it.

This PR is linked to #15836, but no linked issue is marked ready-to-implement yet. Only repository maintainers apply that label, so please wait for a maintainer to mark the issue. Once it is marked, push a new commit or comment /warp-agent-review to re-trigger review.

See the contribution guidelines for the full readiness model.

Powered by Oz

@warp-for-oss warp-for-oss Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thiagohflima

Every PR must be linked to a same-repo issue before Oz can review it.

This PR is linked to #15836, but no linked issue is marked ready-to-implement yet. Only repository maintainers apply that label, so please wait for a maintainer to mark the issue. Once it is marked, push a new commit or comment /warp-agent-review to re-trigger review.

See the contribution guidelines for the full readiness model.

Powered by Oz

@thiagohflima

Copy link
Copy Markdown
Author

@cla-bot check

1 similar comment
@thiagohflima

Copy link
Copy Markdown
Author

@cla-bot check

@cla-bot cla-bot Bot added the cla-signed label Sep 5, 2026
@cla-bot

cla-bot Bot commented Sep 5, 2026

Copy link
Copy Markdown

The cla-bot has been summoned, and re-checked this pull request!

1 similar comment
@cla-bot

cla-bot Bot commented Sep 5, 2026

Copy link
Copy Markdown

The cla-bot has been summoned, and re-checked this pull request!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed external-contributor Indicates that a PR has been opened by someone outside the Warp team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Shell preference silently resets to system default after Homebrew upgrades the shell (canonicalized Cellar path breaks the match)

1 participant