Skip to content

fix(install): restore runtime symlinks after failures - #11579

Merged
jdx merged 1 commit into
jdx:mainfrom
Marukome0743:pr11579
Aug 2, 2026
Merged

jdx merged 1 commit into
jdx:mainfrom
Marukome0743:pr11579

Conversation

@Marukome0743

@Marukome0743 Marukome0743 commented Aug 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • restore runtime symlinks after a backend installation fails and its incomplete install directory is cleaned up
  • limit repair to backends whose install task actually ran and failed
  • preserve the original installation error when symlink repair also fails

Problem and root cause

Runtime aliases can be updated while an installation is in progress. If the backend installation then fails, cleanup removes the incomplete version directory, but a single-failure install path does not run the later full shim and runtime-symlink rebuild. This can leave latest and numeric or prefixed aliases pointing at the removed version.

Implementation

The common install pipeline records the backends whose install tasks fail. After cleanup and config reload, it rebuilds runtime symlinks only for those backends and uses the existing per-directory logic for user, shared, and system installs. Existing valid versions therefore become alias targets again; when no valid version remains, dangling aliases are removed.

The repair is best-effort. A repair error is reported as a warning, while the command still returns the original install failure. Dry runs, plugin setup failures, and disabled-backend validation failures do not trigger repair. This intentionally does not update lockfiles or rebuild shims because the failed version was not installed successfully.

Verification

  • mise run test:e2e e2e/cli/test_install_failure_runtime_symlinks e2e/cli/test_install_parallel_failure
  • mise exec -- cargo test --all-features runtime_symlinks
  • mise exec -- cargo check --all-features
  • mise exec -- cargo clippy --workspace --all-features --all-targets -- -D warnings
  • mise exec -- cargo fmt --all -- --check
  • mise exec -- shfmt -d e2e/cli/test_install_failure_runtime_symlinks
  • mise exec -- shellcheck e2e/cli/test_install_failure_runtime_symlinks

mise run lint was also attempted, but its hk wrapper cannot recognize this Sapling working copy as a Git repository. The relevant Rust, shell formatting, ShellCheck, and Clippy checks above pass individually.

Addresses #6697

AI-assisted — Tool: Codex; model: OpenAI/GPT-5; version: unavailable.

Summary by CodeRabbit

  • Bug Fixes

    • Improved runtime alias handling when installations fail, restoring aliases to valid installations where possible.
    • Preserved existing aliases for dependency-blocked installations.
    • Removed dangling aliases when no valid installation remains.
    • Improved recovery when multiple installations or alias rebuilds fail, with all relevant errors reported.
  • Tests

    • Added end-to-end coverage for dry runs, failed installations, dependency-blocked installations, and dangling aliases.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The change adds backend-aware runtime symlink recovery for failed installations. It tracks attempted failures, restores affected aliases after resolution, aggregates rebuild errors, and adds end-to-end coverage for dry runs, dependency failures, restoration, and dangling aliases.

Changes

Runtime symlink recovery

Layer / File(s) Summary
Backend-aware symlink recovery
src/runtime_symlinks.rs
rebuild_for_toolset delegates to rebuild_for_backends. Rebuild tasks run across install directories, and errors are aggregated.
Failed installation recovery integration
src/toolset/toolset_install.rs
install_with_deps returns attempted failures. install_all_versions collects affected backends and rebuilds their symlinks after configuration reload and resolution.
End-to-end failure validation
e2e/cli/test_install_failure_runtime_symlinks
The test verifies dry-run stability, alias restoration, dependency-blocked alias preservation, failure reporting, and dangling alias removal.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Install as install_all_versions
  participant Deps as install_with_deps
  participant Symlinks as rebuild_for_backends
  participant Backend as Backend
  Install->>Deps: install tool requests
  Deps-->>Install: successes, failures, attempted failures
  Install->>Symlinks: affected backends
  Symlinks->>Backend: rebuild runtime symlinks
  Backend-->>Symlinks: rebuild results
  Symlinks-->>Install: aggregated result
Loading

Possibly related PRs

  • jdx/mise#11207: Related install-lifecycle cleanup for failed or incomplete installations.

Suggested reviewers: jdx, jambalaya56562

Poem

A rabbit watched failed links unwind,
Then rebuilt each path in kind.
Dry runs kept their aliases bright,
Valid installs restored them right.
Dangling links vanished from sight.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes restoring runtime symlinks after failed installations, which is the pull request's primary change.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Marukome0743
Marukome0743 marked this pull request as ready for review August 2, 2026 00:58
@greptile-apps

greptile-apps Bot commented Aug 2, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR restores runtime aliases after failed installation tasks while preserving the original installation error.

  • Tracks only failures from installation tasks that were actually spawned, excluding dependency-blocked and pre-install failures.
  • Rebuilds aliases across all affected backend installation directories and collects repair errors without stopping subsequent repairs.
  • Adds end-to-end and unit coverage for failed installs, blocked dependencies, dry runs, dangling aliases, and multi-repair error handling.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; the current code excludes dependency-blocked installs from repair and continues attempting later runtime-symlink repairs after an earlier repair error.

Important Files Changed

Filename Overview
src/toolset/toolset_install.rs Tracks spawned-task failures separately from blocked or pre-spawn failures and invokes best-effort alias repair only for affected backends, resolving the prior scope issue.
src/runtime_symlinks.rs Adds backend-scoped rebuilding and exhaustively attempts every backend-directory repair before returning an aggregate error, resolving the prior early-abort issue.
e2e/cli/test_install_failure_runtime_symlinks Covers alias restoration, dry-run immutability, blocked-dependent preservation, and dangling-alias removal.

Reviews (4): Last reviewed commit: "fix(install): restore runtime symlinks a..." | Re-trigger Greptile

Comment thread src/toolset/toolset_install.rs Resolved
Comment thread src/runtime_symlinks.rs Resolved
@Marukome0743
Marukome0743 marked this pull request as draft August 2, 2026 01:07
@Marukome0743
Marukome0743 marked this pull request as ready for review August 2, 2026 01:48
@jdx
jdx enabled auto-merge (squash) August 2, 2026 01:54
auto-merge was automatically disabled August 2, 2026 02:06

Head branch was pushed to by a user without write access

@Marukome0743
Marukome0743 marked this pull request as draft August 2, 2026 02:23
@Marukome0743
Marukome0743 marked this pull request as ready for review August 2, 2026 03:13
@jdx
jdx merged commit 7350f5b into jdx:main Aug 2, 2026
29 checks passed
@Marukome0743
Marukome0743 deleted the pr11579 branch August 2, 2026 03:22
This was referenced Aug 2, 2026
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.

2 participants