Skip to content

fix(desktop): surface an actionable hint when Smart App Control blocks a backend DLL - #89636

Open
chelsealong wants to merge 1 commit into
NousResearch:mainfrom
chelsealong:fix/89627-windows-sac-blocked-dll-hint
Open

fix(desktop): surface an actionable hint when Smart App Control blocks a backend DLL#89636
chelsealong wants to merge 1 commit into
NousResearch:mainfrom
chelsealong:fix/89627-windows-sac-blocked-dll-hint

Conversation

@chelsealong

Copy link
Copy Markdown
Contributor

What does this PR do?

With Windows Smart App Control (SAC) enabled, Hermes Desktop's bundled Python interpreter can't load its own C-extension DLLs (e.g. _sqlite3.pyd) — they aren't code-signed, and SAC blocks unsigned binaries with no cloud reputation and offers no exclusion list. The backend process aborts on import before it announces its port, so the desktop app only ever showed the generic:

Hermes couldn't start
The background gateway didn't come up.
Error: Hermes backend exited before it became ready (1).

with the real cause (ImportError: DLL load failed while importing _sqlite3: ...) buried in desktop.log. Full code-signing the bundled Python (the proper long-term fix) is out of scope for this PR — it needs an actual code-signing certificate and release-pipeline change that only maintainers can set up. This PR does what's achievable from the app/docs side: make the failure recognizable and point at a documented workaround.

Related Issue

Fixes #89627

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)

Changes Made

  • apps/desktop/electron/backend-exit-diagnosis.ts (new) — describeBackendExitHint(), a pure function that recognizes the Windows DLL load failed while importing signature in the backend's recent log tail and returns an actionable hint (mentions Smart App Control/antivirus/corrupted install as known causes, links the new docs entry).
  • apps/desktop/electron/main.ts — the backend exit handler (when the backend dies before becoming ready) now appends this hint to the boot-progress error message and the rejected error, instead of only the generic "exited before it became ready" text. No change for any other exit cause (hint is null, message is byte-for-byte the same as before).
  • apps/desktop/electron/backend-exit-diagnosis.test.ts (new) — unit tests for the detector (matches, case-insensitivity, no false positive on an unrelated exit log, empty input).
  • website/docs/user-guide/windows-native.md — new "Common pitfalls" entry documenting the SAC incompatibility and the WSL2 workaround, per the issue's suggestion Support passing morph snapshot id #2 ("If signing is not feasible short-term, document the incompatibility").

How to Test

  1. cd apps/desktop && npx vitest run electron/backend-exit-diagnosis.test.ts — passes (4/4).
  2. Confirmed the test fails without the fix: temporarily removed backend-exit-diagnosis.ts (the file this PR adds) and re-ran the same test — Cannot find module './backend-exit-diagnosis', 1 failed suite.
  3. Full electron test project: npx vitest run --project electron — 110 passed | 1 skipped (unrelated, pre-existing), 1453 passed | 2 skipped.
  4. npx tsc -p tsconfig.electron.json --noEmit — clean.
  5. npx eslint electron/backend-exit-diagnosis.ts electron/backend-exit-diagnosis.test.ts electron/main.ts — clean.
  6. npx vitest run src/app/gateway/hooks/use-gateway-boot.test.tsx --project ui — 13/13 passed (confirms the boot-progress message consumer is unaffected for the non-hint case).

Test output

 RUN  v4.1.10 apps/desktop
 Test Files  1 passed (1)
      Tests  4 passed (4)
 RUN  v4.1.10 apps/desktop
 Test Files  110 passed | 1 skipped (111)
      Tests  1453 passed | 2 skipped (1455)

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix (no unrelated commits)
  • I've added tests for my changes
  • Windows-specific change, reasoned about via code + doc reading (no Windows machine available in this environment to reproduce SAC itself)

Documentation & Housekeeping

  • I've updated relevant documentation (website/docs/user-guide/windows-native.md)
  • N/A — no config keys changed
  • N/A — no architecture/workflow change
  • Cross-platform impact considered: the detector only fires on the Windows-only CPython "DLL load failed while importing" string; non-Windows exits are unaffected (hint stays null, message unchanged byte-for-byte)

AI assistance disclosure

This PR was authored with AI assistance (an autonomous Claude-based coding agent), with the change scoped, implemented, and verified (tests run, lint/typecheck run, pre-fix-vs-post-fix test behavior confirmed) before opening.

…s a backend DLL

Windows Smart App Control blocks Hermes's unsigned bundled Python C
extension DLLs (e.g. _sqlite3.pyd), so the backend aborts on import
before it can announce readiness. The desktop app only showed the
generic "Hermes backend exited before it became ready" message, giving
affected users no lead on what actually happened or how to work around
it (NousResearch#89627).

describeBackendExitHint() recognizes the "DLL load failed while
importing" signature in the backend's recent log output and appends a
pointer to the new Windows guide troubleshooting entry, which documents
the incompatibility and the WSL2 workaround until the bundled Python is
signed.
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/desktop Electron desktop app (apps/desktop/*) platform/windows Native Windows-specific behavior or breakage sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows labels Aug 19, 2026
@Enough1122

Copy link
Copy Markdown
Contributor

AI code review — automated review for reference; please use your judgment.

Review of "fix(desktop): surface an actionable hint when Smart App Control blocks a backend DLL". Nice DX addition: dependency-free pure diagnosis function (testable without Electron), a pattern that matches the real-world Chinese-localized SAC error string, honest docs stating SAC and unsigned bundled Python are incompatible until signing happens (with WSL2 as the workaround), and the hint rides both the UI progress message and the rejection error. One nit:

  • apps/desktop/electron/main.ts:10613 — recentHermesLog() is evaluated twice (once for the hint, once inside the rejection Error); capture it once in a local so both consumers see the same tail even if the log grows between the two reads.

No blocking issues found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have platform/windows Native Windows-specific behavior or breakage sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Windows] Smart App Control blocks unsigned Python DLL (_sqlite3.pyd) → Hermes backend fails to start

3 participants