Skip to content

fix(shell-hook): make prompt modification idempotent to prevent duplication#5686

Open
mango766 wants to merge 1 commit intoprefix-dev:mainfrom
mango766:fix/shell-hook-idempotent-prompt
Open

fix(shell-hook): make prompt modification idempotent to prevent duplication#5686
mango766 wants to merge 1 commit intoprefix-dev:mainfrom
mango766:fix/shell-hook-idempotent-prompt

Conversation

@mango766
Copy link

Summary

Fixes #5599

Running eval "$(pixi shell-hook ...)" multiple times for the same environment currently causes:

  • Bash/Zsh: PS1 prefix keeps getting prepended → (env) (env) (env) $
  • PowerShell: Recursive wrapping of the prompt function → stack overflow crash
  • Nu Shell: Indefinite nesting of PROMPT_COMMAND

Root cause

The prompt modification functions in crates/pixi_core/src/prompt.rs (posix_prompt, powershell_prompt, nu_prompt) unconditionally modify the shell prompt on every invocation, with no check for whether the prompt was already modified.

Notably, the fish_prompt function already handles this correctly by checking if not functions -q __fish_prompt_orig before wrapping.

Fix

Add an idempotency guard using a __PIXI_PROMPT_MODIFIED environment variable. Each prompt function now:

  1. Checks if __PIXI_PROMPT_MODIFIED is already set to the expected value for the current environment
  2. Only modifies the prompt if the guard is not set (i.e., first activation)
  3. Sets the guard after modifying the prompt

This also correctly handles switching between environments — if you activate env A then env B, the guard value changes so the prompt gets updated.

Shells affected

Shell Before After
Bash/Zsh PS1 duplicated on each eval Idempotent ✅
PowerShell Stack overflow on repeated eval Idempotent ✅
Nu Shell Nested prompt wrapping Idempotent ✅
Fish Already idempotent Unchanged ✅
Cmd.exe Already idempotent (@PROMPT replaces) Unchanged ✅
Xonsh No-op Unchanged ✅

Test plan

  • Run eval "$(pixi shell-hook -m <project>)" twice in bash — PS1 should show (env) only once
  • Run (pixi shell-hook) | Out-String | Invoke-Expression twice in PowerShell — no stack overflow
  • Switch environments: activate env A then env B — prompt should update to B
  • Existing test_shell_hook_unix / test_shell_hook_windows tests should still pass

…cation

Add guards to posix, PowerShell, and Nu shell prompt functions so that
running `shell-hook` multiple times for the same environment no longer
causes PS1 prefix duplication (bash/zsh), stack overflow from recursive
prompt wrapping (PowerShell), or indefinite prompt nesting (Nu shell).

Each prompt function now checks a `__PIXI_PROMPT_MODIFIED` env variable
before modifying the prompt, making the operation idempotent. The fish
shell prompt already had this guard via `functions -q __fish_prompt_orig`.

Fixes prefix-dev#5599

Co-Authored-By: Claude (claude-opus-4-6) <noreply@anthropic.com>
@baszalmstra
Copy link
Contributor

  • But this still results in the same behavior when you activate two different environments.
  • Does this work correctly if you do this for two different projects with the same environment name?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Running shell-hook output multiple times causes issues

2 participants