[Bug]: macOS SnapShot test capture fails when endpoint security kills inline osascript#21747

opened26d agobyEekrako

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/desktop

Steps to reproduce

  1. On a Mac with an endpoint security agent (SentinelOne and Kandji ESF are installed on mine), open Settings → SnapShots and turn it on.
  2. Step 1 Access shows Screen Recording: Allowed and Accessibility: Allowed.
  3. Click Test capture and continue.

Expected behavior

The test capture finds the front window and setup continues.

Actual behavior

Setup fails with:

DesktopSnapShotSetupError: Could not capture a test snapshot. Finding the front window failed.

Both permissions are granted. The window lookup in apps/desktop/src/snapShot/ActiveWindow.ts runs /usr/bin/osascript -l JavaScript -e <script>, where the script is the JXA lookup that uses the ObjC bridge (CoreGraphics, AppKit, CGWindowListCopyWindowInfo). The endpoint security agent SIGKILLs osascript when that script arrives inline via -e, so Node reports code: null, signal: "SIGKILL" and setup shows the generic "Finding the front window failed" message.

I ran the same script through T3 Code's own Electron binary (ELECTRON_RUN_AS_NODE=1) in three ways:

How the script is passedResult
osascript -l JavaScript -e <script>killed: {"signal":"SIGKILL","ms":14}
osascript -l JavaScript - with the script on stdinworks, returns the frontmost window JSON
osascript -l JavaScript <file>works

The modifier-pair poller in MacModifierPairShortcutProcess.ts also uses -e but is not killed in any of these modes. Only the ObjC-bridge lookup script triggers it.

This may be the underlying cause of #18595. That issue had the same symptom (inline osascript lookup failing from Electron while it worked from a terminal, both permissions Allowed), and #18857 fixed only the error message. I can't confirm it's the same failure because that report has no exit code or signal.

Impact

Blocks work completely

Version or commit

T3 Code (Nightly) 0.1.1-nightly.20261019.3348

Environment

macOS 27.0.1 (26A434), Apple silicon, Electron 44.4.5, SentinelOne + Kandji ESF installed

Logs or stack traces

shell
1DesktopSnapShotSetupError: Could not capture a test snapshot. Finding the front window failed.
2osascript child exit: code=null signal=SIGKILL (~14 ms)

Workaround

None in the app. Passing the script on stdin (osascript -l JavaScript -) avoids the kill. I have a small fix doing that in runMacLookup(), with a test, and will open a PR.


Investigated and filed with T3 Code using Claude Opus 5.5.

Synced from GitHub

Still reproduces on 0.1.6-nightly.20261031.3956 (macOS 27.0.1, Apple silicon, SentinelOne agent 26.1.4 installed). The desktop trace shows the same code: null, SIGKILL from runMacLookup() about 7 ms after the spawn.

One correction to the analysis above: the trigger is the size of the inline -e argument, not the ObjC bridge. A JXA script with no ObjC calls, only a comment, gets killed once it passes 938 bytes:

sh
1# 938 bytes: exits 0
2osascript -l JavaScript -e "1//$(printf 'a%.0s' $(seq 1 935))"
3# 939 bytes: exits 137 (SIGKILL)
4osascript -l JavaScript -e "1//$(printf 'a%.0s' $(seq 1 936))"
  • AppleScript (osascript -e) with a 2,000-byte script is not killed. Only -l JavaScript -e hits the limit.
  • The same long script works from a file and from stdin (osascript -l JavaScript -).
  • The lookup script is 1,226 bytes, so it is over the limit. The modifier-pair poller in MacModifierPairShortcutProcess.ts is under it, which explains why it survives.
  • Every part of the lookup script works through -e when run on its own under the limit, including CGWindowListCopyWindowInfo, the window loop and frontmostApplication.

This supports the stdin approach in #21749. Any future osascript -l JavaScript -e call with a script over about 900 bytes will fail the same way on machines with this agent.


Investigated with T3 Code using Claude Opus 5.5.