Skip to content

fix(install): shorten staging path segments to clear Windows MAX_PATH - #2941

Open
Mohammed Alkindi (MohammedAlkindi) wants to merge 1 commit into
microsoft:mainfrom
MohammedAlkindi:fix/shorten-resolution-staging-paths
Open

fix(install): shorten staging path segments to clear Windows MAX_PATH#2941
Mohammed Alkindi (MohammedAlkindi) wants to merge 1 commit into
microsoft:mainfrom
MohammedAlkindi:fix/shorten-resolution-staging-paths

Conversation

@MohammedAlkindi

Copy link
Copy Markdown
Contributor

Description

The staging root used a full uuid4().hex and each destination slot a full sha256 hexdigest: 96 hex characters before any real path. On a realistic Windows project root that pushes staged paths past 260 and fails the install with WinError 206.

The root is now 12 hex characters and the slot 16, freeing 68. _STAGING_NAME matches both lengths, so an upgrade still collects staging roots left by an older version.

Fixes #2896

Type of change

  • Bug fix

Testing

ruff check and ruff format --check on all three files: clean.

Touched test files: 48 passed, 3 failed. All three fail identically on the unmodified source. Two need symlink privileges this machine lacks (WinError 1314); test_workspace_lock_serializes_concurrent_processes is timing-dependent and failed 3/3 without the change.

Full tests/unit/install/: 2135 passed, 411 skipped, 51 failed, dominated by that same symlink limitation. I did not attribute all 51 individually, so I am not claiming the suite is green here.

  • Tested locally
  • All existing tests pass
  • Added tests for new functionality

Not a spec change.

🤖 Generated with Claude Code

The staging root used a full uuid4().hex and each destination slot a full sha256 hexdigest, 96 hex characters before any real path. On a realistic Windows project root that pushed staged paths past 260 and failed the install with WinError 206.

The root is now 12 hex characters and the slot 16, freeing 68. The orphan-detection pattern matches both lengths so an upgrade still collects staging roots left by an older version.

Closes microsoft#2896

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.

🟡 Changes recommended

Two moderate test coverage and path-length validation issues remain unresolved.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Shortens staging path identifiers to prevent Windows MAX_PATH failures while preserving legacy cleanup compatibility.

Changes:

  • Limits staging roots to 12 hex characters.
  • Limits destination slots to 16 hex characters.
  • Adds path-length and cleanup regression tests.
File summaries
File Summary
tests/unit/install/test_resolution_staging_relocate.py Adds path-length coverage; needs the windows_compat marker and a full nested staged-file path assertion.
tests/unit/install/test_install_transaction.py Tests cleanup for current and legacy staging-root formats.
src/apm_cli/install/resolution_staging.py Implements shorter identifiers and legacy staging-root matching.
Review details

Suppressed comments (1)

tests/unit/install/test_resolution_staging_relocate.py:244

  • The length calculation only measures the staging root through the 16-character slot; the destination's nested components are hashed away, and no representative file path is appended below replacement. This can pass while a path such as the nested backlog/release-notes/... content from issue #2896 still exceeds MAX_PATH, so build a representative nested staged-file path and assert its full length.
    relative_len = len(str(replacement.relative_to(modules))) + len("apm_modules") + 1
    old_scheme_relative_len = relative_len + (32 - 12) + (64 - 16)
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

assert [path.name for path in modules.iterdir()] == ["mixedorg"]


def test_prepare_replacement_slot_names_fit_windows_max_path(tmp_path: Path) -> None:
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.

Install fails on Windows with WinError 206 (path too long) / WinError 3 due to double-hashed staging paths

2 participants