Skip to content

bug(install): install.ps1 missing uv tool update-shell -- conductor not on PATH for new processes #115

@franklixuefei

Description

@franklixuefei

Problem

The PowerShell install script (install.ps1) installs conductor to ~/.local/bin/conductor.exe via uv tool install, but does not call uv tool update-shell to add ~/.local/bin to the persistent user PATH (Windows registry HKCU\Environment\Path).

Result: conductor works in the install shell (uv temporarily modifies process PATH), but all new terminals, sub-processes, CI agents, and IDE extensions cannot find it.

Evidence

Verified on Windows 11, PowerShell 7.5, uv 0.7.8, Conductor v0.1.9

# 1. Conductor binary EXISTS at the expected location
PS> Test-Path "$env:USERPROFILE\.local\bin\conductor.exe"
True

# 2. But ~/.local/bin is NOT in the persistent user PATH
PS> [Environment]::GetEnvironmentVariable("PATH", "User") -match '\.local\\bin'
False

# 3. uv confirms the bin directory
PS> uv tool dir --bin
C:\Users\xuefl\.local\bin

# 4. New terminal cannot find conductor
PS> # (open new PowerShell window)
PS> conductor --version
conductor: The term 'conductor' is not recognized as a name of a cmdlet, function,
script file, or executable program.

# 5. Running update-shell fixes it
PS> uv tool update-shell
Updated PATH to include executable directory C:\Users\xuefl\.local\bin

# 6. After update-shell, user PATH is fixed
PS> [Environment]::GetEnvironmentVariable("PATH", "User") -match '\.local\\bin'
True

# 7. New terminal now finds conductor
PS> # (open new PowerShell window)
PS> conductor --version
Conductor v0.1.9

Production impact

This caused a 35-minute hang in a CI-like pipeline where:

  1. A parent process installed conductor and could find it (process PATH was modified)
  2. The parent spawned sub-agents via a task system (each gets a fresh process)
  3. Sub-agents inherited the system PATH (no ~/.local/bin) and could not find conductor
  4. Sub-agents retried indefinitely with no timeout, blocking the entire pipeline

Analysis of 50 conductor invocation logs on the affected machine showed a 50% crash rate -- 25 out of 50 runs had identical 2-event crash signatures (workflow_started + agent_started, then EOF), all with the same file size (~90,750 bytes), consistent with immediate "command not found" failures.

Why sub-processes don't inherit the fix

Windows process PATH inheritance chain:

Registry (HKCU\Environment\Path)
  -> Terminal startup (reads registry, sets process env)
    -> Parent process (inherits from terminal)
      -> Child process (inherits from parent)

uv tool install modifies the parent process PATH only. Child processes inherit from the parent, not the registry. uv tool update-shell writes to the registry, which is read by all future terminals.

Reproduction

# 1. Install conductor (fresh install or reinstall)
irm https://aka.ms/conductor/install.ps1 | iex

# 2. Verify the bug
[Environment]::GetEnvironmentVariable("PATH", "User") -match '\.local\\bin'
# Expected: True
# Actual: False

# 3. Open a NEW terminal (fresh process, no inherited PATH modifications)
conductor --version
# Expected: Conductor v0.1.9
# Actual: 'conductor' is not recognized

# 4. Apply workaround
uv tool update-shell
# Now restart terminal -- conductor works

Proposed fix

Add uv tool update-shell after successful install in install.ps1:

# install.ps1, after the "Conductor $tagName installed successfully" message:

# Ensure ~/.local/bin is on the persistent user PATH so conductor is
# discoverable by all processes, not just the current shell.
# Idempotent -- safe to run on every install/upgrade.
& uv tool update-shell 2>&1 | Out-Null

Why this is the correct fix

  1. Follows uv's own pattern -- uv adds its own bin dir to PATH during self-install via the same mechanism
  2. Idempotent -- uv tool update-shell is safe to run repeatedly; it only adds the entry if missing
  3. Minimal change -- one line after the existing install success message
  4. No downstream workarounds needed -- all consumers (terminals, CI, sub-processes, IDE extensions) automatically get the correct PATH on next session

Why NOT fixing at the consumer layer

We've implemented workarounds in our tooling (PATH injection in sub-agent prompts, registry persistence in tool resolvers), but these are defense-in-depth measures. The root cause is that the install script should produce a working PATH for all processes, not just the current shell.

Environment

  • OS: Windows 11 Enterprise 24H2
  • PowerShell: 7.5.1
  • uv: 0.7.8
  • Conductor: v0.1.9
  • Install method: irm https://aka.ms/conductor/install.ps1 | iex

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