Skip to content

fix(install): don't crash the PowerShell installer when $PROFILE is unset#2469

Open
abhay-codes07 wants to merge 1 commit into
headroomlabs-ai:mainfrom
abhay-codes07:fix/install-ps1-empty-profile-crash
Open

fix(install): don't crash the PowerShell installer when $PROFILE is unset#2469
abhay-codes07 wants to merge 1 commit into
headroomlabs-ai:mainfrom
abhay-codes07:fix/install-ps1-empty-profile-crash

Conversation

@abhay-codes07

Copy link
Copy Markdown
Contributor

Description

The PowerShell installer (scripts/install.ps1) crashes at the very end on any machine where PowerShell cannot resolve the current user's profile path.

Ensure-ProfileBlock locates the profile with:

$profileDir = Split-Path -Parent $PROFILE

$PROFILE is an empty string when PowerShell cannot compute the profile path for the current user, which happens for a fresh account with no Documents folder yet, a service or CI context, or a redirected profile. Split-Path -Parent '' then throws:

Split-Path : Cannot bind argument to parameter 'Path' because it is an empty string.

Because the script runs under $ErrorActionPreference = 'Stop', that terminates the whole installer with a non-zero exit, even though it happens after the headroom wrapper and the persistent User PATH entry were already written. The user sees a scary Split-Path error and assumes the install failed.

Fix

Skip the profile convenience block when $PROFILE is empty and log why. Ensure-PathEntry already persists the User PATH for new sessions, so the only thing skipped is auto-refreshing PATH inside the current profile file, which does not exist in that environment anyway. Well-behaved environments with a real $PROFILE are unchanged.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Performance improvement
  • Code refactoring (no functional changes)

Changes Made

  • scripts/install.ps1: early-return from Ensure-ProfileBlock with an informational message when $PROFILE is null or empty, before the Split-Path call.

Testing

  • Unit tests pass (pytest)
  • Linting passes (ruff check .)
  • Type checking passes (mypy headroom)
  • New tests added for new functionality
  • Manual testing performed

Test Output

$ python -m pytest tests/test_install/test_native_installers.py -q
1 passed, 1 skipped

# The PowerShell lifecycle test was failing on main before this change and now passes:
$ python -m pytest "tests/test_install/test_native_installers.py::test_powershell_native_installer_supports_persistent_docker_lifecycle" -q
1 passed

Real Behavior Proof

  • Environment: Windows 11, Python 3.12, Windows PowerShell 5.1, project venv (uv sync --extra proxy), pytest in the venv.
  • Exact command / steps: ran install.ps1 under a temp USERPROFILE with no Documents folder (the same setup the installer test uses). Confirmed $PROFILE resolves to an empty string in that context and that Split-Path -Parent $PROFILE throws there, then re-ran the installer test with the fix.
  • Observed result: before the fix the installer aborted with Split-Path : Cannot bind argument to parameter 'Path' because it is an empty string and exit code 1 (and the test failed); after the fix the installer completes, writes the wrapper and PATH entry, logs that it skipped the profile update, and the test passes. Ran against the actual script.
  • Not tested: a real end-user account whose Documents folder is redirected to a network share.

Review Readiness

  • I have performed a self-review
  • This PR is ready for human review

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have updated the CHANGELOG.md if applicable

…nset

`Ensure-ProfileBlock` did `Split-Path -Parent $PROFILE` to locate the user's
PowerShell profile. PowerShell leaves `$PROFILE` as an empty string when it
cannot resolve the profile path for the current user (a fresh account with no
Documents folder yet, a service or CI context, a redirected profile). Split-Path
then throws "Cannot bind argument to parameter 'Path' because it is an empty
string", and because the script runs under `$ErrorActionPreference = 'Stop'`
that aborts the whole installer with a cryptic error at the very end, after the
`headroom` wrapper and the persistent User PATH entry were already written. The
user sees a non-zero exit and assumes the install failed.

Skip the profile convenience block when `$PROFILE` is empty and log why. The
PATH is already persisted for new sessions by the separate `Ensure-PathEntry`
call, so the only thing skipped is auto-refreshing PATH inside the current
profile, which does not exist in that environment anyway.

This is exactly the path
`test_powershell_native_installer_supports_persistent_docker_lifecycle` drives
(it runs the installer under a temp HOME whose profile cannot be resolved); the
test now passes instead of failing on the Split-Path error.
Copilot AI review requested due to automatic review settings July 21, 2026 17:41

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@JerrettDavis JerrettDavis left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approved. The guard is correctly placed before Split-Path, and the behavior is scoped to the missing-profile-path case while still preserving the persistent User PATH update for new sessions.

Local validation in an isolated PR worktree:

  • uv run --frozen --extra dev python -m pytest tests/test_install/test_native_installers.py::test_powershell_native_installer_supports_persistent_docker_lifecycle -q -> 1 passed
  • git diff --check upstream/main...HEAD -> clean

@github-actions

Copy link
Copy Markdown
Contributor

PR governance

This PR follows the template and is marked ready for human review.

@github-actions github-actions Bot added the status: ready for review Pull request body is complete and the author marked it ready for human review label Jul 21, 2026
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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

Labels

status: ready for review Pull request body is complete and the author marked it ready for human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants