fix(installing.commands): key selectProjectByDir graph by project.rootDir#12380
Conversation
…tDir `selectProjectByDir` constructs a single-entry `ProjectsGraph` for the non-workspace install path. It was using `searchedDir` (`opts.dir`) as the key, but downstream `recursive()` builds `manifestsByPath` from the projects array (keyed by `project.rootDir`) and then looks up entries via `manifestsByPath[rootDir]` where `rootDir` is drawn from `Object.keys(selectedProjectsGraph)`. When `opts.dir` and `project.rootDir` differ in platform-normalized form (most often on Windows due to drive-letter casing), the lookup falls through as `undefined` and `pnpm add <pkg>` crashes with: Cannot destructure property 'manifest' of 'manifestsByPath[rootDir]' as it is undefined Pin the graph key to `project.rootDir` in both `installing/commands/src/installDeps.ts` and `installing/commands/src/import/index.ts`, so the keys stay in sync with `manifestsByPath`. Closes pnpm#12379 Written by an agent (Claude Code, claude-opus-4-7).
|
💖 Thanks for opening this pull request! 💖 |
Code Review by Qodo
1.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📜 Recent review details⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
🧰 Additional context used📓 Path-based instructions (1)**/*.{ts,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (3)📚 Learning: 2026-05-14T09:04:00.133ZApplied to files:
📚 Learning: 2026-06-05T13:47:05.929ZApplied to files:
📚 Learning: 2026-06-05T13:47:26.046ZApplied to files:
🔇 Additional comments (6)
📝 WalkthroughWalkthroughTwo one-line fixes in ChangesWindows Path Normalization Fix
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install timed out. The project may have too many dependencies for the sandbox. 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. Comment |
PR Summary by QodoFix non-workspace install graph keys to use project.rootDir WalkthroughsDescription• Key single-project ProjectsGraph entries by project.rootDir for consistent downstream lookups. • Prevent Windows non-workspace pnpm add crash caused by path normalization differences. • Add changeset documenting the regression fix and patch release impact. Diagramgraph TD
A["installDeps.ts"] --> B["selectProjectByDir()"] --> D[("ProjectsGraph (key=rootDir)")] --> E["recursive()"] --> F[("manifestsByPath (key=rootDir)")] --> G["importers.map reads manifest"]
C["import/index.ts"] --> B
High-Level AssessmentThe following are alternative approaches to this PR: 1. Normalize/canonicalize graph keys (realpath/lowercase drive)
2. Make recursive() lookup tolerant (fallback search by path equivalence)
Recommendation: The PR’s approach is the best tradeoff: keying the single-entry ProjectsGraph by project.rootDir fixes the mismatch at the source with minimal behavioral surface area. The alternatives (path canonicalization or tolerant lookup) are broader changes with higher platform/edge-case risk than necessary for this regression. File ChangesBug fix (2)
Documentation (1)
|
|
Code review by qodo was updated up to the latest commit 426fae9 |
|
Code review by qodo was updated up to the latest commit cbb308c |
Summary
Closes #12379.
selectProjectByDirconstructs a single-entryProjectsGraphfor the non-workspace install path (called frominstallDeps.ts:266andimport/index.ts:147). It was usingsearchedDir(opts.dir) as the key, but downstreamrecursive()ininstalling/commands/src/recursive.tsbuildsmanifestsByPathfrom the projects array (keyed byproject.rootDir) and then looks up entries viamanifestsByPath[rootDir]whererootDiris drawn fromObject.keys(selectedProjectsGraph). Whenopts.dirandproject.rootDirdiffer in platform-normalized form (most often on Windows due to drive-letter casing), the lookup falls through asundefinedandpnpm add <pkg>crashes with the exact error in the issue:Reporter's stack trace pins it to
installing/commands/src/recursive.ts:240(const { manifest } = manifestsByPath[rootDir]inside theimporters.mapbody), reached viarecursive→recursiveInstallThenUpdateWorkspaceState→installDeps.Pin the graph key to
project.rootDirin bothselectProjectByDircallsites so the keys stay in sync withmanifestsByPath. The bug only surfaced on the single-project (non-workspace)pnpm addpath because workspace flows go through a different graph builder that already keys byproject.rootDir.Test commands
Could not reproduce on macOS (drive-letter casing isn't a concern there), but verified the logic on the source side. The change is small and targeted: same
projectlookup, just a different key for the single-entry graph object. Both call sites use the identical fix.Notes
The bug was introduced in 11.6.0 in
feat(pacquet): configurational dependencies support (#12285)whenrecursive.tswas added.Summary by CodeRabbit
pnpm add <pkg>would fail with a manifest error when run outside a workspace. The issue occurred due to path normalization differences, particularly when drive-letter casing varied between the current directory and the project root.