Standard Notes electron app fails trying to get userData

I’m trying to use the standardnotes desktop app on the 2024-05-15 12:06:01 generation of the 23.11 channel (so app version 3.181.23). On startup it fails with the following error:

app threw an error during load
Error: Failed to get ‘userData’ path
at get userDataDir [as userDataDir] (/nix/store/071qfwp63ymdgf9bz8dvnllpi7qhlxiw-standardnotes-3.181.23/share/standardnotes/app.asar/dist/index.js:2:144961)
at new mi (/nix/store/071qfwp63ymdgf9bz8dvnllpi7qhlxiw-standardnotes-3.181.23/share/standardnotes/app.asar/dist/index.js:2:204264)
at /nix/store/071qfwp63ymdgf9bz8dvnllpi7qhlxiw-standardnotes-3.181.23/share/standardnotes/app.asar/dist/index.js:2:286229
at 354 (/nix/store/071qfwp63ymdgf9bz8dvnllpi7qhlxiw-standardnotes-3.181.23/share/standardnotes/app.asar/dist/index.js:2:287331)
at n (/nix/store/071qfwp63ymdgf9bz8dvnllpi7qhlxiw-standardnotes-3.181.23/share/standardnotes/app.asar/dist/index.js:2:832666)
at /nix/store/071qfwp63ymdgf9bz8dvnllpi7qhlxiw-standardnotes-3.181.23/share/standardnotes/app.asar/dist/index.js:2:833177
at Object. (/nix/store/071qfwp63ymdgf9bz8dvnllpi7qhlxiw-standardnotes-3.181.23/share/standardnotes/app.asar/dist/index.js:2:833189)
at Module._compile (node:internal/modules/cjs/loader:1271:14)
at Object…js (node:internal/modules/cjs/loader:1326:10)
at Module.load (node:internal/modules/cjs/loader:1126:32)
Uncaught exception Error: Failed to get ‘userData’ path
at get userDataDir [as userDataDir] (/nix/store/071qfwp63ymdgf9bz8dvnllpi7qhlxiw-standardnotes-3.181.23/share/standardnotes/app.asar/dist/index.js:2:144961)
at new mi (/nix/store/071qfwp63ymdgf9bz8dvnllpi7qhlxiw-standardnotes-3.181.23/share/standardnotes/app.asar/dist/index.js:2:204264)
at /nix/store/071qfwp63ymdgf9bz8dvnllpi7qhlxiw-standardnotes-3.181.23/share/standardnotes/app.asar/dist/index.js:2:286229
at 354 (/nix/store/071qfwp63ymdgf9bz8dvnllpi7qhlxiw-standardnotes-3.181.23/share/standardnotes/app.asar/dist/index.js:2:287331)
at n (/nix/store/071qfwp63ymdgf9bz8dvnllpi7qhlxiw-standardnotes-3.181.23/share/standardnotes/app.asar/dist/index.js:2:832666)
at /nix/store/071qfwp63ymdgf9bz8dvnllpi7qhlxiw-standardnotes-3.181.23/share/standardnotes/app.asar/dist/index.js:2:833177
at Object. (/nix/store/071qfwp63ymdgf9bz8dvnllpi7qhlxiw-standardnotes-3.181.23/share/standardnotes/app.asar/dist/index.js:2:833189)
at Module._compile (node:internal/modules/cjs/loader:1271:14)
at Object…js (node:internal/modules/cjs/loader:1326:10)
at Module.load (node:internal/modules/cjs/loader:1126:32)
Trace/breakpoint trap (core dumped)

My best guess is it crashes because this is an electron app that expects to be able to write to the userdata directory ~/.config, which on nixOS requires root permissions. Is this a common problem with a common workaround? Or is my guess totally off and some other issue is afoot? I’m using the stock Sway DE.

I am on unstable and I used to get something similar, but after a few updates I now get:

05:19:11.029 › APPIMAGE env is not defined, current application is not an AppImage
extServer: Server started at http://127.0.0.1:45653
05:19:12.001 › APPIMAGE env is not defined, current application is not an AppImage
[145905:0518/051915.082601:ERROR:gl_surface_presentation_helper.cc(260)] GetVSyncParametersIfAvailable() failed for 1 times!

Not sure what the issue is and I haven’t got time to look at the moment, but perhaps it is not writing to ~/.config?

It appears I have this exact problem with every electron app. Standard Notes, Element Desktop, and Signal Desktop all produce this exact same error about failing to get the userData path.

Trying to debug the failure, I ran npx @electron/asar extract /nix/store/rz33svqxfhw2abs5ydy1masqb5qwbliz-signal-desktop-6.39.1/lib/Signal/resources/app.asar ~/signal and looked at the ~/signal/app/user_config.js which has the following logic:

var import_electron = require("electron");
var import_base_config = require("./base_config");
var import_config = __toESM(require("./config"));
var Errors = __toESM(require("../ts/types/errors"));
let userData;
if (import_config.default.has("storagePath")) {
  userData = String(import_config.default.get("storagePath"));
} else if (import_config.default.has("storageProfile")) {
  userData = (0, import_path.join)(
    import_electron.app.getPath("appData"),
    `Signal-${import_config.default.get("storageProfile")}`
  );
}
if (userData !== void 0) {
  try {
    (0, import_fs.mkdirSync)(userData, { recursive: true });
  } catch (error) {
    console.error("Failed to create userData", Errors.toLogFormat(error));
  }
  import_electron.app.setPath("userData", userData);
}
console.log(`userData: ${import_electron.app.getPath("userData")}`);

The last line is where the exception was thrown. I checked ~/signal/config/default.json and it contains neither storagePath nor storageProfile, so it should fall through all of the above and it’s the specific statement import_electron.app.getPath("userData") that fails.

Looking at the electron source code for this function, the 'userData' string is aliased to 'appData', which according to the linked electron comment resolves to “$XDG_CONFIG_HOME or ~/.config on Linux”.

In my /etc/nixos/configuration.nix file I have the following:

environment.variables = {
  XDG_CONFIG_HOME = "$HOME/.config";
};

which is useless, granted, because spec-conformant applications are supposed to fallback to $HOME/.config if $XDG_CONFIG_COME is not defined, but whatever we’re debugging so I defined it anyway. I can also run echo $XDG_CONFIG_HOME from the same terminal in which I’m trying to start any of these apps and can confirm it is set to $HOME/.config.

So here we come back to my initial hypothesis that within the actual app.getPath function there is some functionality checking whether the appData path is writable before returning it - which it won’t be, because ~/.config requires root permissions to write to on nixOS. So I don’t know what to do here. I can’t redefine $XDG_CONFIG_HOME to something else, because other things (like my desktop environment) rely on that value being correct in order to work.

The issue was that my ~/.config was set to require root permissions for writes for some reason, don’t know how that happened; switched it to being owned by my user and this fixed the problem.

1 Like