MemberJunction / MemberJunction/MJ
mj app install writes dynamicPackages into a comment — Open App server packages silently never load
- Dominant language
- TSQL
- Stars
- 29
- Forks
- 6
- Avg merge
- 2d 1h
- Merged PRs (30d)
- 323
Description
## Summary
`mj app install` writes the `dynamicPackages` block into the **first `module.exports = {` it finds in the file** using a comment-blind regex. In MJ's own default MJAPI config scaffold that match is the *example* inside the header doc comment — so every entry the installer writes lands inside `/* … */` and is silently inert.
The install reports success. `mj app list` shows the app `Active`. But MJAPI never loads the app's server package, and **nothing anywhere reports a problem**.
## Root cause
`@memberjunction/open-app-engine/dist/install/config-manager.js` → `InsertBeforeModuleExportsClose`:
```js
const inlineMatch = content.match(/module\.exports\s*=\s*\{/);
```
No comment stripping. The MJAPI scaffold ships with this in its header comment:
```js
* To override ANY default setting, simply add it to this file.
* For example:
*
* module.exports = {
* telemetry: { ... }
* };
*/
```
That is the first match, so `FindMatchingBracket` returns the example's closing brace and the section is inserted before it — inside the comment.
## Reproduction
1. Start from the stock MJAPI `mj.config.cjs` scaffold (the one whose header documents an example `module.exports = { … };`).
2. `mj app install `.
3. Open `apps/MJAPI/mj.config.cjs` — the `dynamicPackages` block is inside the `/** … */` header comment, and the comment's example has been mangled (its closing `* };` consumed).
4. Start MJAPI: no `Loading Open App server packages…` entries for the installed app. No error.
Observed on `@memberjunction/cli` 5.48.0; `InsertBeforeModuleExportsClose` is byte-identical in 5.49.0.
## Impact
Silent and total: the app is installed in the database but its server package never loads, so its resolvers, class registrations and startup side effects are all missing. The failure surfaces much later as an unrelated-looking "entity not found" / missing-GraphQL-operation problem, with no breadcrumb back to the installer.
## Suggested fix
Strip comments and strings before locating the insertion point, or anchor on a `module.exports` match that is not inside a comment. A cheap defensive addition: after writing, `require()` the config and assert the section is actually present — this bug is invisible precisely because nothing verifies the write.
## Workaround
Move the block into the real `module.exports` by hand after every install/upgrade. Note that once a genuine `dynamicPackages:` key exists, `EnsureDynamicPackagesSection` early-returns and `AddEntryToDynamicArray` dedupes on PackageName+AppName — so a corrected file stays correct on subsequent installs.
Contributor guide
Research direction
Start in @memberjunction/open-app-engine/dist/install/config-manager.js at InsertBeforeModuleExportsClose and reproduce with the stock MJAPI mj.config.cjs using mj app install. The fix is done when dynamicPackages is inserted into the real module.exports rather than the header example, and MJAPI loads the installed app's server package.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100