MemberJunction / MemberJunction/MJ

mj dev workspace generates strict-peer-dependencies=true for a tree with 11 pre-existing unmet peers, so every later pnpm install (and therefore every mj app install) fails

Open
#4,130 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TSQL
Stars
29
Forks
6
Avg merge
2d 1h
Merged PRs (30d)
323

Description

## Summary

`mj dev workspace` writes `strict-peer-dependencies=true` into the generated `.npmrc`, but the tree it generates cannot satisfy it. MJ and `bizapps-caliber` carry pre-existing peer mismatches, so any `pnpm install` in the generated workspace that has to re-resolve fails with `ERR_PNPM_PEER_DEP_ISSUES`. In practice that means every `mj app install`.

## Environment

MJ `next`, CLI `@memberjunction/cli/6.1.0-edge.4`, Node 24.14.1, pnpm 10.33.0, macOS arm64. 17 member repos generated by `mj dev workspace`.

## What happened

The generated `.npmrc` is exactly:

```
package-manager-strict=false
strict-peer-dependencies=true
auto-install-peers=true
```

The first `pnpm install` the generator runs itself succeeds, because it writes the lockfile as it goes. Later installs succeed too, as long as nothing changes — pnpm prints `Lockfile is up to date, resolution step is skipped` and never evaluates peers.

The failure appears the moment something forces re-resolution. `mj app install` adds the app's packages to `packages/MJAPI/package.json` and `packages/MJExplorer/package.json` and then runs `pnpm install`, which re-resolves and fails:

```
ERR_PNPM_PEER_DEP_ISSUES Unmet peer dependencies
```

11 unmet peers, all pre-existing, none involving a `@mj-biz-apps/*` package:

- `@stryker-mutator/vitest-runner` wants `vitest@2`, the tree has 4
- six `bizapps-caliber` projects want `eslint@8`, the tree has 9
- `MJ/packages/AI/CorePlus` wants `date-fns@3`, the tree has 4
- `MJ/packages/AI/MCPClient` wants `express@4`, the tree has 5
- the Databricks package's `ws` peer is unsatisfied

Because `mj app install` treats a non-zero `pnpm install` as a failed step, the install finalizes the app as `Disabled` rather than `Active` and leaves the host unable to build. That was reproducible on every app until the setting was flipped.

`auto-install-peers=true` does not help here: it installs *missing* peers, and every one of these is a *mismatched* peer.

## Root cause

`NPMRC_BASE_LINES` in `packages/MJCLI/src/lib/dev-workspace/build.ts:73-77` hardcodes the three lines, and `BuildNpmrc` (`build.ts:225-227`) emits them verbatim. The command writes the file at `packages/MJCLI/src/commands/dev/workspace/index.ts:174`.

The setting is a reasonable default in the abstract. The problem is that the generator has no way to know whether the joined tree can satisfy it, and it does not check. The union of N repos' dependency graphs is strictly more peer-constrained than any one of them: each repo's own CI only ever resolves its own graph, so a mismatch between two repos, or between a repo and a hoisted devDependency, is invisible until the generator joins them. The generator already unions and reports `pnpm.overrides`, `patchedDependencies`, `packageExtensions` and `peerDependencyRules` conflicts across members (`ResolveMemberPnpmBlocks`, `build.ts:448-484`) — peer satisfiability is the one cross-member property it asserts without measuring.

The failure mode is also unusually confusing because it is delayed. The setting is latent until an unrelated command happens to force re-resolution, and the error then names packages the developer was not touching.

## Workaround

Set `strict-peer-dependencies=false` in the generated `.npmrc`. Every app install then completes `Active` on the first pass. The edit is lost on any `mj dev workspace` regeneration.

## Notes

Options range from the generator emitting `false` (or emitting it conditionally when it detects an unsatisfiable union), to fixing the underlying peer ranges in MJ and `bizapps-caliber`, to generating targeted `peerDependencyRules.allowedVersions` entries for the known mismatches. Happy to send a PR for whichever you prefer.

Contributor guide

Open the contributing guide

Research direction

Read NPMRC_BASE_LINES and BuildNpmrc in packages/MJCLI/src/lib/dev-workspace/build.ts, then trace the write in packages/MJCLI/src/commands/dev/workspace/index.ts. Reproduce the generated workspace install and mj app install behavior, including peer resolution. Done means the chosen strict-peer-dependency policy is generated consistently and later installs no longer fail on the reported pre-existing peers.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
build-system, cli, devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.