fix(desktop): open files from a second instance started with --user-data-dir (#3020) by Jocs · Pull Request #5375 · marktext/marktext · GitHub
Skip to content

fix(desktop): open files from a second instance started with --user-data-dir (#3020) - #5375

Merged
Jocs merged 4 commits into
developfrom
fix/3020-second-instance-argv
Sep 16, 2026
Merged

Jocs merged 4 commits into
developfrom
fix/3020-second-instance-argv

Conversation

@Jocs

@Jocs Jocs commented Sep 15, 2026 •

Copy link
Copy Markdown
Member

Closes #3020

Summary

If MarkText is started with --user-data-dir while an instance using that directory is already running, the file is not opened. For example, the report starts portable MarkText twice:

MarkText.exe .\TestDoc1.md --user-data-dir .\Data
MarkText.exe .\TestDoc2.md --user-data-dir .\Data

Instead of opening TestDoc2.md in a new tab, the running instance shows ArgError: option requires argument: --user-data-dir.

Cause. The running instance parses the argv of the second-instance event. Electron documents that this argv "will not be exactly the same list of arguments as those passed to the second instance. The order might change and additional arguments might be appended" (see electron/electron#32933, closed as not planned). On develop (Electron 42, macOS), the running instance receives:

[<exe>, '--user-data-dir', '--allow-file-access-from-files', '--enable-avfoundation', <app path>, 'TestDoc2.md', 'Data']

Switches come first, so --user-data-dir is separated from Data. It is also followed by another switch, so arg throws. Only the --user-data-dir=Data form survives this.

Fix. Electron's recommendation is additionalData.

  • A starting instance passes its own process.argv to app.requestSingleInstanceLock({ argv }).
  • The second-instance handler parses that unchanged copy. If a second instance from a version without this change sends no data, the handler falls back to argv as before.

Type of change

  • Bug fix (non-breaking, fixes an issue)
  • New feature (non-breaking, adds functionality)
  • Breaking change (causes existing functionality to change)
  • Documentation update

Test plan

  • New tests added
    • issue-3020-second-instance-args.spec.ts (e2e, built app) opens a document, then starts a second instance with second.md --user-data-dir <same dir>. It checks that the second instance exits with 0 (the failure message includes its output), that the running instance receives one second-instance event and its listeners throw nothing, and that second.md opens as a tab without a new window.
    • On develop it fails with ArgError: option requires argument: --user-data-dir. With this change it passes (3/3 repeated runs).
  • A standalone probe on the built app tried five argument forms for the second instance: file --user-data-dir dir, --user-data-dir dir file, --user-data-dir=dir file, --user-data-dir dir --new-window file, and file --user-data-dir dir --allow-file-access-from-files. On develop, every form except --user-data-dir=dir threw ArgError and opened nothing. With this change all five open the file, and --new-window opens it in a new window.
  • pnpm run typecheck passes, eslint reports 0 errors on the changed files, all desktop unit tests pass (818/818), and launch.spec.ts + tabs.spec.ts pass.
  • Tested on: macOS (built app via Playwright). The e2e job covers Linux. Windows was not run.

Notes for reviewers

  • Listener wrapper in the spec. An exception thrown by a main-process listener hangs an Electron app driven by Playwright. The spec therefore wraps the app's own second-instance listeners in a try/catch that records what they throw. Without the wrapper, the running instance hangs and never acknowledges the second instance. The second instance then carries on as an instance of its own, so the spec would time out instead of reporting the ArgError.
  • --no-sandbox on Linux. Playwright launches Electron with --no-sandbox on Linux, because the CI runner can't use Chromium's SUID sandbox. The spec passes the same switch to the second instance; without it, the second instance aborts at startup there, before it reaches the running instance.
  • Conflict with fix(desktop): launch normally when NODE_ENV=development is set (#5053) #5374. This PR and fix(desktop): launch normally when NODE_ENV=development is set (#5053) #5374 (error.unexpectedErrorWithMessage #5053) change adjacent lines in packages/desktop/src/main/index.ts: that PR changes the if around the lock, this one changes the lock call. Whichever merges second needs a trivial rebase.

🤖 Generated with Claude Code


By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.

@github-actions

github-actions Bot commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Jocs and others added 4 commits September 16, 2026 11:31
…ata-dir (#3020)

The running instance parsed the argv of the `second-instance` event, but
Chromium lists switches before the other arguments there and appends
switches of its own (--allow-file-access-from-files and, on macOS,
--enable-avfoundation). `marktext file.md --user-data-dir Data` therefore
arrived as `--user-data-dir --allow-file-access-from-files … file.md Data`,
and parsing threw "option requires argument: --user-data-dir" instead of
opening the file in a tab.

A starting instance now sends its own process.argv as the additional data
of the single instance lock, and the running instance parses that copy.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…-data-dir (#3020)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The e2e job on Linux saw the second instance end with no exit code. Keep
its output and exit signal for the failure message, count the
second-instance events the running instance receives, and check the
opened tab even when the exit status is unexpected.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… Linux

On the Linux CI runner the second instance aborted at startup ("The SUID
sandbox helper binary was found, but is not configured correctly") before
it reached the running instance. Playwright launches Electron with
--no-sandbox on Linux, so pass the same switch to the second instance.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Jocs
Jocs force-pushed the fix/3020-second-instance-argv branch from f258124 to e9a3df3 Compare September 16, 2026 03:32
@Jocs
Jocs merged commit dba33ad into develop Sep 16, 2026
10 checks passed
@Jocs
Jocs deleted the fix/3020-second-instance-argv branch September 16, 2026 03:55
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 this pull request may close these issues.

Portable mode does not work fully with commandline

1 participant