MemberJunction / MemberJunction/MJ

mj app install writes dynamicPackages into a comment — Open App server packages silently never load

Open
#3,301 1 comment 0 reactions 0 assignees View on GitHub
bug
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.