Skip to content

"Cannot find module 'sharp'" on Windows only after upgrading to 26.0.11 #8970

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Nantris opened this issue Mar 17, 2025 · 69 comments · Fixed by #9067
Closed

"Cannot find module 'sharp'" on Windows only after upgrading to 26.0.11 #8970

Nantris opened this issue Mar 17, 2025 · 69 comments · Fixed by #9067

Comments

@Nantris
Copy link

Nantris commented Mar 17, 2025

After upgrading to 26.0.11 it seems Sharp isn't being properly bundled or run. None of our config changed except changing win.publisherName to win.signToolOptions.publisherName.

I'm not sure how to go further in investigating this. Any advice appreciated!

@mmaietta
Copy link
Collaborator

Hiya! Can you share a minimum reproducible repo that I can test locally with and/or create a unit test around? Would like to assist but need more information first.

@Nantris
Copy link
Author

Nantris commented Mar 17, 2025

Hey @mmaietta thanks for your reply.

I did find the problem - in files we had this rule, which worked fine in 25.x but not in 26.x (Sharp version didn't change):

!**/node_modules/sharp/install/*

Simply removing this is enough of a fix for us and probably only adds a tiny bit to the package size, but I do wonder why that would now be breaking in 26.x (and seemingly only on Windows.)

Thanks again!

@Nantris
Copy link
Author

Nantris commented Mar 18, 2025

Actually, I must have overlooked something because that's definitely not resolving the issue now...

@Nantris
Copy link
Author

Nantris commented Mar 18, 2025

Hm... I really thought I had this working but every attempt now results in this same issue. I'm not sure if I changed something else or if what I thought fixed it never really did. I'll update soon.

@Nantris
Copy link
Author

Nantris commented Mar 18, 2025

@mmaietta I did notice that there's nothing under app.asar.unpacked from Sharp (or any other Node dependencies.

@mmaietta
Copy link
Collaborator

Yeahhhh, definitely need a minimum repro repo for this unfortunately. The node collector logic was completely migrated to TS from Golang to support pnpm amongst other things, and a migration to electron/asar in order to support electron/fuses integration

@Nantris
Copy link
Author

Nantris commented Mar 18, 2025

Thanks as always for the great work and for your help @mmaietta!


I put together a repro here: https://github.com/Nantris/electron-builder-repro-8970

It requires Yarn v4 (which I think should be used automatically as long as you have corepack enabled?)

Repro steps:

  1. yarn install
  2. yarn package
  3. Run executable in win-unpacked

This isn't an exact copy of our config and may not be 100% correct in every regard, but it should at least output the app.asar.unpacked folder I would think. Alas, it does not.

@mmaietta
Copy link
Collaborator

Well this is odd indeed. Your .asar doesn't have any node modules dir present. What version of electron-builder are you upgrading from? I'm wondering if this is a yarn 4-specific bug

@Nantris
Copy link
Author

Nantris commented Mar 19, 2025

Thanks as always for all you do @mmaietta!

I was wondering if it might be related to Yarn 4 myself.

We upgraded from 25.1.8 and I believe I verified this affects 26.0.0 specifically but I'm not certain now.

It's super strange to me that while Windows fails, Linux builds remain unaffected. I haven't had a chance to test macOS. Maybe there's some sort of path issue that makes this only work on POSIX?

@Nantris
Copy link
Author

Nantris commented Mar 19, 2025

I confirmed macOS is unaffected. So only Windows has the problem.

I also tried setting supportedArchitectures in .yarnrc.yml even though it works in dev, and as expected, no difference.

@Julusian
Copy link
Contributor

I am experiencing this issue too, but with a different dependency. this works with 26.0.2 (before the node_module collector change), but not with 26.0.11. I am using yarn 4.7.0
Reported by a windows user, but it looks like it affects all our builds.

If I look inside the app.asar, there is no node_modules folder at all, we have 10+ direct dependencies that should be included there.

I should add a disclaimer that we are using a lightly patched app-builder-lib, but that should only be including more node_modules than usual loose inside the resources directory.

The snippet of our config that I expect could affect this is:

files: ['**/*', 'assets/*'],
			extraResources: [
				{
					from: '../dist',
					to: '.',
					filter: ['**/*', '!.yarn'],
				},
			],

@mmaietta
Copy link
Collaborator

@beyondkmp can you please take a look at this when you have a chance? Seems there's an issue specifically on Windows, and it may be specific to yarn 4.

I'm trying to write a unit test from my side, but once corepack is enabled in the docker container to support a yarn4-scoped test, subsequent runs of other unit tests break due to corepack now being enabled.

@mmaietta
Copy link
Collaborator

mmaietta commented Mar 20, 2025

Image

Confirming that the node module collection logic is not pulling any node modules when using yarn 4, even on macOS dir target. For some reason, npm list -a --include prod --include optional --omit dev --json --long --silent returns an empty dependency tree when running from the cwd, whereas running it from root seems to work correctly

@Nantris
Copy link
Author

Nantris commented Mar 20, 2025

@mmaietta that's very strange! Because our macOS build worked unless I'm crazy.

Edit: Reconfirming macOS built properly with [email protected]

@mmaietta
Copy link
Collaborator

mmaietta commented Mar 20, 2025

Hmmm, I'm running off latest master

I was able to resolve the dependency collection by changing the rootDir to no longer be the app dir, but the project root dir, however, now JSON.parse fails on parsing the scripts response due to malformed JSON in the npm list CLI output

"concurrently \\"npm run build:main\\" \\"npm run build:renderer\\""

Trying to figure out how to get around this issue now, as at least the dependency tree is being returned correctly. Suggestions welcome as I'm still pretty sick and my mind is an absolute ball of fuzz right now

@stq
Copy link

stq commented Mar 20, 2025

I'm getting similar problem on 26.0.11 - multiworkspace project, unpacking asar shows there are no node_modules there at all.

@mmaietta
Copy link
Collaborator

@stq, is that also a yarn 4 project?

@stq
Copy link

stq commented Mar 20, 2025

@stq, is that also a yarn 4 project?

No, npm9/node20. Downgrading to 26.0.2 fixed issue.

@mmaietta
Copy link
Collaborator

@stq would you mind putting together a minimum reproducible repo since yours isn't yarn 4? I'd like to create a dedicated unit test for this multi-workspace project as we already have some two-package.json app fixtures, but it seems like we're missing a use case.

@mmaietta
Copy link
Collaborator

mmaietta commented Mar 20, 2025

@Nantris can you try this patch-package? It works all of a sudden for me on macos target, still need to setup a test env in a windows VM though
patches/app-builder-lib+26.0.11.patch

diff --git a/node_modules/app-builder-lib/out/util/appFileCopier.js b/node_modules/app-builder-lib/out/util/appFileCopier.js
index 79dee3f..3308f61 100644
--- a/node_modules/app-builder-lib/out/util/appFileCopier.js
+++ b/node_modules/app-builder-lib/out/util/appFileCopier.js
@@ -144,7 +144,7 @@ function validateFileSet(fileSet) {
 }
 /** @internal */
 async function computeNodeModuleFileSets(platformPackager, mainMatcher) {
-    const deps = await (0, node_module_collector_1.getNodeModules)(platformPackager.info.appDir);
+    const deps = await (0, node_module_collector_1.getNodeModules)(platformPackager.projectDir);
     builder_util_1.log.debug({ nodeModules: deps }, "collected node modules");
     const nodeModuleExcludedExts = getNodeModuleExcludedExts(platformPackager);
     // serial execution because copyNodeModules is concurrent and so, no need to increase queue/pressure

@Nantris
Copy link
Author

Nantris commented Mar 20, 2025

@mmaietta I'm sorry to report it didn't resolve the issue. But macOS always worked for us, so maybe there are two issues here? It's pretty confusing.

@mmaietta
Copy link
Collaborator

Ok that is weird, as it looks like it packaged correctly for me with just that change. Launches just fine too.
Image

@Nantris
Copy link
Author

Nantris commented Mar 21, 2025

@mmaietta you're testing on the master branch, right? Unfortunately I can't get that working here, apparently due to this issue, so I guess we may be testing slightly different setups.

That image is from macOS, right?

@beyondkmp
Copy link
Collaborator

@Nantris can you try this patch-package? It works all of a sudden for me on macos target, still need to setup a test env in a windows VM though patches/app-builder-lib+26.0.11.patch

diff --git a/node_modules/app-builder-lib/out/util/appFileCopier.js b/node_modules/app-builder-lib/out/util/appFileCopier.js
index 79dee3f..3308f61 100644
--- a/node_modules/app-builder-lib/out/util/appFileCopier.js
+++ b/node_modules/app-builder-lib/out/util/appFileCopier.js
@@ -144,7 +144,7 @@ function validateFileSet(fileSet) {
 }
 /** @internal */
 async function computeNodeModuleFileSets(platformPackager, mainMatcher) {
-    const deps = await (0, node_module_collector_1.getNodeModules)(platformPackager.info.appDir);
+    const deps = await (0, node_module_collector_1.getNodeModules)(platformPackager.projectDir);
     builder_util_1.log.debug({ nodeModules: deps }, "collected node modules");
     const nodeModuleExcludedExts = getNodeModuleExcludedExts(platformPackager);
     // serial execution because copyNodeModules is concurrent and so, no need to increase queue/pressure

This will include all dependencies from projectDir, while the dependencies in appDir should only be a subset of projectDir's dependencies and don't need to be entirely included.

@mmaietta
Copy link
Collaborator

mmaietta commented Mar 21, 2025

@mmaietta you're testing on the master branch, right? Unfortunately I can't get that working here, yarnpkg/berry#5715, so I guess we may be testing slightly different setups.
That image is from macOS, right?

Should be the same setup. That was on a default yarn install from a fresh git clone, then just patched the appFileCopier.js directly within node_modules/app-builder-lib. Built within a Windows arm64 VM

@Nantris
Copy link
Author

Nantris commented Mar 21, 2025

@mmaietta this is my bad, but actually even more confusing. Originally I tested against our project and not against the repro.

The patch works on the repro :)

Does not work on our project :(


Edit 1: Investigating further. If I come across anything I'll update.
Edit 2: I updated our config to match the repro as closely as I can and I can't find any discrepancies, but our real project still fails to bundle node_modules. I guess I need to next test the repro on macOS to see if that fails for me as it did for you @mmaietta, and beyond that I'm at a total loss.

@mmaietta
Copy link
Collaborator

mmaietta commented Mar 21, 2025

Oh lordy, this is becoming a conundrum n' a half.

I was going to suggest this as an easy fix. Checks the appDir (current behavior) and if no dependencies found, it has a fallback up the tree to the projectDir

export async function getNodeModules(projectDir: string, appDir: string): Promise<NodeModuleInfo[]> {
  const collector = await getCollectorByPackageManager(appDir)
  let deps = await collector.getNodeModules()
  if (!deps.length && appDir !== projectDir) {
    deps = await (await getCollectorByPackageManager(projectDir)).getNodeModules()
  }
  return deps
}

But since it doesn't work for your original/source project, I'm not sure where to go from here either.

Might need @stq to get back to us on a minimum repro project so I can do a deeper dive since this doesn't seem isolated to yarn 4. Might be due to multi-workspace setups, which is my hunch, but I need a local setup to repro and write a unit test for. Otherwise I'm just stabbing in the dark to find a needle in a haystack 😅

I think it may be useful to add a log.warn when there's no deps found to prevent the issue going unnoticed by unsuspecting victims

@Nantris
Copy link
Author

Nantris commented Mar 21, 2025

The repro I provided does indeed fail for me on macOS, whereas my project does not.


Might be due to multi-workspace setups, which is my hunch

Seems very possible, since our project is indeed a Yarn workspace, but all the native deps are at the project root so one wouldn't think it would be the cause, but it's the most promising theory I'd say.

The only other differences I can find are:

  1. Our build config file is nested in a directory in our real project whereas it's in the project root in the repro, but I don't think there's any plausible way that could make a difference?
  2. We have additional native dependencies.

I noticed some debug statements in app-builder-lib. I wonder if I can force those to output and try to find any discrepancies between the repro and our real project?

For now I guess we're going to stick with 26.0.2 and pin hopes on an independent repro hopefully pointing to whatever this other issue is.

@mmaietta
Copy link
Collaborator

I noticed some debug statements in app-builder-lib. I wonder if I can force those to output and try to find any discrepancies between the repro and our real project?

Set env var DEBUG=electron-builder and extract the relevant logs maybe? Might be a bit long, so try using markdown to have it a collapsible section

@beyondkmp
Copy link
Collaborator

@Nantris When you have time, Could you provide your dependencies and project results so we can try to reproduce the issue?

@Nantris
Copy link
Author

Nantris commented Apr 2, 2025

@beyondkmp it's a rather sprawling monorepo so while I can provide a list of native dependencies, providing a list of all the dependencies and how they're specified isn't likely to be feasible.

Could you clarify what you mean by project results? I guess specifically the contents of app.asar.unpacked would be the main interest here?

@Nantris
Copy link
Author

Nantris commented Apr 2, 2025

@beyondkmp I wonder if #8571 is likely to be related to this?

@beyondkmp
Copy link
Collaborator

@beyondkmp I wonder if #8571 is likely to be related to this?

It is indeed related to this. However, we are currently unable to reproduce your issue, so we need your help in providing the project structure and dependencies. This way, we can check if we can reproduce it locally.

@Nantris
Copy link
Author

Nantris commented Apr 4, 2025

I appreciate how helpful you guys are! Unfortunately I don't know what we can realistically share. If not for this being a monorepo it would be easier to suggest what possibly to try. Although all of our native dependencies live in the root package.json if that's of any value.

Besides providing a repro, I wonder if you might have any advice about where I could throw some logging lines in the code changed in #8571. Maybe I can figure out more precisely where it fails and report back directly with that.

@mmaietta
Copy link
Collaborator

mmaietta commented Apr 5, 2025

@Nantris are you in the ElectronJS Discord group by chance? You can reach out to me via there (I'm grouped under "maintainer" in the electron-builder channel) and we can discuss this in more real-time w/ @beyondkmp as well.

@beyondkmp
Copy link
Collaborator

beyondkmp commented Apr 7, 2025

@Nantris Currently, two bugs(#9010 & #9013 ) have been identified in the New Node Modules Collector. Once these two bugs are fixed, your issue might also be resolved.

@Nantris
Copy link
Author

Nantris commented Apr 11, 2025

Thank you both! I'll loop back to check if those fix them once they're released. Otherwise I'll find you guys on the electron-builder channel when (if?) things slow down here.

@mmaietta
Copy link
Collaborator

Released v26.0.13

@Nantris Nantris closed this as completed Apr 12, 2025
@Nantris
Copy link
Author

Nantris commented Apr 12, 2025

Looks good! Problem is resolved! Thank you so much!

@Nantris
Copy link
Author

Nantris commented Apr 13, 2025

Quite confusingly, this is broken again. I wonder if maybe a dependency of electron-builder upgraded since I tested and re-broke it. Trying to find some clues currently.

Unfortunately I don't have a working yarn.lock to consult since I installed it as a test. I only found later that my committed version from the next day behaves differently.

@Nantris Nantris reopened this Apr 13, 2025
@Nantris
Copy link
Author

Nantris commented Apr 13, 2025

I really can't find anything different. Here's the story:

  1. I tested 26.0.13 on our Windows machine. It worked but I didn't commit anything because I was in the middle of some work on my Linux machine
  2. I finished the work on the Linux machine and committed. Then I upgraded electron-builder there and committed
  3. I did a little more work
  4. I pulled the changes to Windows and built. I get the error from the title.
  5. I checked out the last commit that I had been using on Windows that had worked in testing. I installed 26.0.13 and ran it, but now the error occurs

I tried messing with the dependencies of electron-builder but most or all of them would theoretically have been in existence and used during my previously working test. I tried reverting some of them but no luck. I have no ideas right now.

The only thing I can think is that my first test of 26.0.13 was invalid somehow, but I'm all but certain I went to node_modules/electron-builder/package.json to confirm the version (not just relying on yarn why electron-builder which often lies about the installed version.)

@tom2strobl
Copy link

Experiencing something similiar after upgrading from 25.1.8 (works), to 26.0.12 (doesn't) on mac (haven't tested windows yet).

We use yarn v3 in a monorepo setup with dual pkg.json and after upgrading no node_module folder is packaged into the asar. (and consequently asarUnpack has nothing to unpack).

Relevant settings (simplified):

{
  asar: true,
  asarUnpack: ['**\\*.{node,dll}'],
  files: ['dist', 'node_modules', 'package.json'],
  directories: {
    app: join('..', 'desktop-release', 'app'),
    output: join('..', 'desktop-release', 'build')
  }
}

I can confirm these directories to exist:

desktop-release/app/dist
desktop-release/app/node_modules
desktop-release/app/package.json

Now after upgrading to 26.0.13 I can confirm the node_modules folder being present again and therefore asarUnpack also working. But interestingly not all modules are present.

After running the packaged app I get:

Uncaught Exception:
Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@mapbox/node-pre-gyp' imported from /Applications/thappinquestion.app/Contents/Resources/app.asar/node_modules/get-windows/lib/windows.js
at Object.getPackageJSONURL (node:internal/modules/package_json_reader:268:9)
at packageResolve (node:internal/modules/esm/resolve:778:81)
at moduleResolve (node:internal/modules/esm/resolve:864:18)
at defaultResolve (node:internal/modules/esm/resolve:994:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:685:12)
at #cachedDefaultResolve (node:internal/modules/esm/loader:634:25)
at ModuleLoader.resolve (node:internal/modules/esm/loader:617:38)
at ModuleLoader.getModuleJobForImport (node:internal/modules/esm/loader:273:38)
at ModuleJob._link (node:internal/modules/esm/module_job:135:49)

I can see that get-windows itself has been asar-unpacked.
If I extract the asar of the packaged .app I can see that @mapbox/node-pre-gyp is not in node_modules.

Now if I roll back to 25.1.8 again, things work just fine.

I saw that get-windows uses

import preGyp from '@mapbox/node-pre-gyp';

in https://github.com/sindresorhus/get-windows/blob/6e84e52e43469e2836f5b11e9de5d239a9963b54/lib/windows.js#L5

although its only listed as optionalDependency in https://github.com/sindresorhus/get-windows/blob/6e84e52e43469e2836f5b11e9de5d239a9963b54/package.json#L90

Does that confuse the electron-builder dependency walker?

I did try to add @mapbox/node-pre-gyp manually as a dependency to my desktop-release package.json, but that didn't help – I suppose the get-windows repo would need to specify it as a direct dependency for it to work, could that be the case?

@beyondkmp
Copy link
Collaborator

@tom2strobl It's mainly related to the structure of your monorepo. Can you provide a minimal reproducible demo similar to your monorepo's structure? You can refer to the demos provided in these two issues(#9000 & #9011)

@tom2strobl
Copy link

@beyondkmp I see, thanks for getting back to me. Here's a minimal repro: https://github.com/tom2strobl/electron-builder-monorepo-repro

Let me know if I can help any further! Appreciating you guys a lot

@Nantris
Copy link
Author

Nantris commented Apr 18, 2025

Fwiw I don't think it's anything specific to get-windows that you're seeing. We also use that package but all the same problems seem to apply to all native deps (on Windows only.)

Thanks for putting together a repro!

@beyondkmp
Copy link
Collaborator

beyondkmp commented Apr 19, 2025

@beyondkmp I see, thanks for getting back to me. Here's a minimal repro: https://github.com/tom2strobl/electron-builder-monorepo-repro

Let me know if I can help any further! Appreciating you guys a lot

@tom2strobl
Thank you very much for the demo you provided. Under the settings of this demo, the new version really can't get node_modules.

root cause

The npm list command returns empty when executed in desktop-release because the package.json in desktop-release has "installConfig": { "hoistingLimits": "workspaces" }, causing the node_modules folder to lack the library, resulting in an empty return. Then, electron-builder executes npm list in the project directory (desktop), which is not empty, but the package.json's dependencies in that directory are empty, so it returns empty again. Ultimately, this leads to no node_modules being packaged.

Due to the limitations of npm list in this configuration, the only solution I can think of at present is to modify your configuration to solve this problem.

There are two solutions:

  1. Ensure the "dependencies" in the package.json files of desktop and desktop-release are identical, as required by the two package.json setup.
  2. Remove the following from the desktop-release package.json and link node_modules script.
    "installConfig": {
      "hoistingLimits": "workspaces"
    }

Additionally, the postinstall script link-modules in desktop-release is no longer needed in the new version. Removing it can also save some build time.

@Nantris
Copy link
Author

Nantris commented Apr 19, 2025

Perhaps not an ideal solution, but I'm pretty sure that we work around that same issue (?) by just putting native dependencies in the root monorepo dependencies, rather than in a subpackage.

@tom2strobl
Copy link

@beyondkmp thanks a lot for the swift reply!

The npm list command returns empty when executed in desktop-release because the package.json in desktop-release has "installConfig": { "hoistingLimits": "workspaces" }, causing the node_modules folder to lack the library, resulting in an empty return. Then, electron-builder executes npm list in the project directory (desktop), which is not empty, but the package.json's dependencies in that directory are empty, so it returns empty again. Ultimately, this leads to no node_modules being packaged.

Thanks for the explanation! I love it when the answer is not just a black magic box

  1. Ensure the "dependencies" in the package.json files of desktop and desktop-release are identical, as required by the two package.json setup.
  2. Remove the following from the desktop-release package.json and link node_modules script.> "installConfig": {
    "hoistingLimits": "workspaces"
    }
    Additionally, the postinstall script link-modules in desktop-release is no longer needed in the new version. Removing it can also save some build time.

Sorry if that's a dumb question but whats the point of a dual package.json setup if they have identical dependencies? Just the devDependencies? Or do you just simply mean that all desktop-release deps need to be in desktop, but desktop can have more (which are not hoisted and therefore in root anyway).

Wasn't the point that only native dependencies go into the the "production" pkg.json so we know which ones to rebuild? Hoisting was necessary to make sure they are physically in a different location. Being able to hoist was pratically the only reason we had to use yarn because most monorepo setups fail if you need multiple node_modules locations

Or wait... are you essentially implying all of this is not necessary anymore? Could you elaborate how you know which dependencies in the desktop pkg.json are native dependencies? Or do you just rebuild all (wouldn't that be wildly inefficient though)?

We currently need to npm rebuild <depname> --update binary one dependency (doesn't matter as its targeted) and run electron-rebuild --force --types prod,dev,optional --module-dir over desktop-release/app to rebuild the native dependencies for each platform. How would that look like on a single pkg.json? Or is electron-builder nowadays smart enough to only rebuild stuff with native dependencies on its own?

@beyondkmp
Copy link
Collaborator

beyondkmp commented Apr 23, 2025

@tom2strobl

It should now be possible to automatically rebuild native modules since it has been switched to electron/rebuilder.

Indeed, the dependencies in the release package.json can differ from those in the app — this was my misunderstanding.

You can try Solution 2:

Remove the following from the desktop-release package.json

"installConfig": {
  "hoistingLimits": "workspaces"
}

delete that configuration and check if the app can be packaged and run correctly?

@tom2strobl
Copy link

@beyondkmp
well, that is quite a change with a lot of consequences across the board, but I gave it a shot.

link-modules obviously needed to go since all modules are now in root.

Our electron-rebuild script for dev needed to change as well and had some trouble since now the app dependencies are in a different folder than the actual node_modules, since they are hoisted to the root now. Luckily there is some randomly undocumented (?) property to allow different build and root paths from electron/rebuild#250 :

// file is truncated for brevity
import { rebuild } from '@electron/rebuild'
const result = await rebuild({
  // desktop-release
  buildPath: join(import.meta.dirname, '..', '..', '..', 'desktop-release', 'app'),
  // actual monorepo root
  projectRootPath: join(import.meta.dirname, '..', '..', '..')
})

I got it running in dev when electron-builder is out of the picture. Now when I try to package there are a couple of weirdnesses:

First of all, whenever I run electron-builder build it generates a package-lock.json although I don't want to use npm. With [email protected] this does not happen. If I then try to run any yarn command in root I get:

Internal Error: appname@workspace:.: This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile

Removing the package-lock.json and running yarn once fixes this.

When trying to package it also errors:

📦 Starting packaging...
  • electron-builder  version=26.0.13 os=24.0.0
  • loaded configuration  file=/Users/user/dev/appname/desktop/tooling/scripts/electron-builder.ts
  • installing production dependencies  pm=npm platform=darwin arch=arm64 projectDir=/Users/user/dev/appname/desktop appDir=/Users/user/dev/appname/desktop-release/app
  ⨯ npm process failed ERR_ELECTRON_BUILDER_CANNOT_EXECUTE
Exit code:
1
Error output:
npm error Cannot read properties of null (reading 'package')
npm error A complete log of this run can be found in: xyz
  failedTask=build stackTrace=Error: npm process failed ERR_ELECTRON_BUILDER_CANNOT_EXECUTE
Exit code:
1
Error output:
npm error Cannot read properties of null (reading 'package')
npm error A complete log of this run can be found in: xyz

seeing the pm=npm makes me think that yarn is not recognized correctly I guess? I couldnt see anything in the docs on how to override the package manager manually.
Looking into the produced log file I see:

38 verbose stack TypeError: Cannot read properties of null (reading 'package')
38 verbose stack     at set root (/Users/user/.nvm/versions/node/v22.14.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/node.js:748:35)
38 verbose stack     at set root (/Users/user/.nvm/versions/node/v22.14.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/node.js:814:20)
38 verbose stack     at Arborist.reify (/Users/user/.nvm/versions/node/v22.14.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js:220:21)
38 verbose stack     at async Install.exec (/Users/user/.nvm/versions/node/v22.14.0/lib/node_modules/npm/lib/commands/install.js:150:5)
38 verbose stack     at async Npm.exec (/Users/user/.nvm/versions/node/v22.14.0/lib/node_modules/npm/lib/npm.js:207:9)
38 verbose stack     at async module.exports (/Users/user/.nvm/versions/node/v22.14.0/lib/node_modules/npm/lib/cli/entry.js:74:5)
39 error Cannot read properties of null (reading 'package')

I tried running it from the repo root but that (nicely) errors with ⨯ Expected to be run from the desktop dir.
It's quite a mess unfortunately where I feel like multiple parts are busted.

I reverted everything to how it was before and used [email protected] again and everything worked flawlessly again. No erreneous package-lock.json, no dev problems, no packaging problems, all available in the asar, flawless unpacking of whats necessary.

@beyondkmp
Copy link
Collaborator

@tom2strobl

Your mono repo is a bit too complex.

So, let's just remove this configuration. At least in your repro demo, removing this configuration allowed the build to succeed.

"installConfig": {
  "hoistingLimits": "workspaces"
}

@tom2strobl
Copy link

tom2strobl commented Apr 25, 2025

@beyondkmp
Just to be clear, that's what I did in the big repo which resulted in what I described above. It's the same in the reproduction repo for me though.

If I remove the hoistingLimits in the repro demo I

  1. still get pm=npm in the logs:
  • electron-builder  version=26.0.13 os=24.0.0
 [...]
  • installing production dependencies  --> pm=npm <-- platform=darwin arch=arm64 [etc...]
  1. there is still a npm package-lock.json being produced which shouldnt be the case
  2. running any yarn command like eg. yarn workspace @buildermono/desktop webpack afterwards errors in
Internal Error: buildermono@workspace:.: This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile

So it appears to me that some change after 25.1.8 just generally rendered yarn workspaces incompatible, even though the docs actually recommend using yarn.

@beyondkmp
Copy link
Collaborator

@tom2strobl
This is indeed an issue. In a mono repo, having both package-lock.json and yarn.lock causes problems because the current logic relies on these lock files to determine the package manager. As a result, issues like yours occur—where Yarn is used, but it gets misidentified as npm. Let me figure out a better way to identify the package manager.

@Nantris
Copy link
Author

Nantris commented Apr 25, 2025

Package manager can be defined in the package.json, I think under the engines key? I know it's a bit of an escape hatch, but having people manually specify it in these edge cases doesn't seem too crazy as a workaround.

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 a pull request may close this issue.

8 participants