Skip to content

[Bug]:Linux/Hyprland: SSH environment setup fails because Electron safeStorage reports encryption unavailable #2880

Description

@Dillpickleschmidt

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 Arch/Omarchy Hyprland with Electron 41.5.0, ensure Secret Service is available:

    • gnome-keyring-daemon is running
    • secret-tool works after keyring unlock
  2. Start desktop dev mode:

    bun run dev:desktop
  3. Add a desktop-managed SSH environment.

Related upstream Electron issue: electron/electron#39789, fixed by electron/electron#49054. Updating Electron to a version containing that fix is likely preferred.

Expected behavior

SSH launch/tunnel succeeds and the saved environment credentials are persisted.

Actual behavior

SSH launch/tunnel succeeds, but credential persistence fails:

Unable to persist saved environment credentials.

safeStorage.isEncryptionAvailable() returns false even though Secret Service/libsecret is available.

Impact

Blocks work completely

Version or commit

No response

Environment

Arch/Omarchy Hyprland

Logs or stack traces

Screenshots, recordings, or supporting files

No response

Workaround

Until Electron is updated to 42.x, I verified this temporary workaround works in apps/desktop/src/main.ts:

if (process.platform === "linux") {
  Electron.app.commandLine.appendSwitch("password-store", "gnome-libsecret");
}

Note: this may break or bypass native behavior on other Linux environments like KDE.

Activity

  1. added
    bugSomething is broken or behaving incorrectly.
    needs-triageIssue needs maintainer review and initial categorization.
    on May 30, 2026
  2. changed the title [-][Bug]:[/-] [+][Bug]:Linux/Hyprland: SSH environment setup fails because Electron safeStorage reports encryption unavailable[/+] on May 30, 2026
  3. JerkyTreats commented on Jul 23, 2026

    @JerkyTreats

    Confirmed on current main at b41e89eba9cd232cc3257b400fc30972a9b53438 through the Remote link flow, so this is not limited to SSH-managed environments.

    Environment

    • Arch Linux with Omarchy
    • Hyprland on Wayland
    • Electron 41.5.0
    • gnome-keyring-daemon is running and owns org.freedesktop.secrets
    • The user D-Bus session is available at /run/user/1000/bus

    Remote link reproduction

    1. Launch the desktop app from current main without a --password-store override.
    2. Open Add Environment and select Remote link.
    3. Enter a reachable HTTPS backend and a valid one-time pairing code.
    4. Select Add environment.

    The remote descriptor lookup and bearer bootstrap complete, but registration fails when the desktop tries to persist the local connection catalog:

    Could not register connection: ConnectionTransientError: Could not save the local connection catalog: Desktop secure storage is unavailable in this system context.
    

    This is especially disruptive for the Remote link flow because the bearer bootstrap consumes the one-time pairing code before local persistence fails.

    Controlled backend probe

    A minimal safeStorage probe using the same Electron build reports:

    without override
    backend=basic_text
    encryptionAvailable=false
    
    with --password-store=gnome-libsecret
    backend=gnome_libsecret
    encryptionAvailable=true
    

    Current main does not set a password-store switch. The catalog store then correctly refuses to persist credentials through the non-encrypting basic_text backend.

    The failure therefore requires this combination:

    • Electron does not recognize Hyprland for automatic Linux password-store selection
    • Chromium falls back to basic_text
    • T3 Code correctly fails closed for an unencrypted connection catalog
    • A working Secret Service implementation is present but was not selected

    The explicit gnome-libsecret switch is a verified workaround on this system.

    Suggested acceptance criteria

    • On Hyprland with a working org.freedesktop.secrets service, Electron selects an encrypted backend and Remote link registration persists successfully.
    • Systems without a usable encrypted secret store continue to fail closed.
    • Native backend selection on other Linux desktops, especially KDE, is not regressed.
  4. viganogabriele commented on Jul 23, 2026

    @viganogabriele

    Confirming this on Omarchy (Hyprland), using the t3code-nightly-bin AUR package (Electron-based desktop build).

    Same symptom, slightly different surface: pairing a remote environment failed with

    Could not register connection: ConnectionTransientError: Could not save the local connection catalog: Desktop secure storage is unavailable in this system context.
    

    Confirmed Secret Service was fully functional before hitting this (secret-tool store/lookup round-tripped fine, gnome-keyring-daemon --components=pkcs11,secrets running, org.freedesktop.secrets registered on the session bus) — so this matches the report that safeStorage.isEncryptionAvailable() returns false despite libsecret being available, rather than an actual missing keyring.

    The workaround works from the outside too, not just patched into main.ts: launching the desktop binary with the Electron switch directly resolves it:

    t3code-nightly --password-store=gnome-libsecret
    

    Made this permanent via a user-level .desktop override (~/.local/share/applications/) adding the flag to Exec=, since editing the AUR-shipped /usr/share/applications/*.desktop gets clobbered on package updates.

    +1 on prioritizing the Electron 42.x bump referenced above — until then, might be worth shipping the password-store=gnome-libsecret switch by default on Linux (as already suggested) rather than requiring users to hit this cryptic error first.

  5. FelipeAfonso commented on Aug 3, 2026

    @FelipeAfonso

    Another manifestation of this, and probably the most severe one: the same basic_text fallback also breaks T3 Connect sign-in entirely — and unlike the SSH/Remote-link paths above, it doesn't fail closed with a clear error.

    Symptom: every sign-in method (OAuth, email code, passkey) ends with Clerk's raw API error "You are signed out". The failing request is the rotating-token exchange:

    GET https://clerk.t3.codes/v1/client/sign_ins/sia_...?...&rotating_token_nonce=...&_is_native=1&_electron_sdk_version=0.0.24
    → 401 {"errors":[{"code":"signed_out","long_message":"You are signed out"}]}
    

    Mechanism: with safeStorage.isEncryptionAvailable() false, @clerk/electron's storage adapter (wired in DesktopClerk.ts via storage({ path: stateDir })) silently drops every token write — unencryptedFallback is not enabled, and its only diagnostic is a one-time console.warn on main-process stdout, invisible unless the AppImage was launched from a terminal. Clerk rotates the client token right before the nonce exchange, the rotated token is dropped, the exchange runs unauthenticated, and FAPI answers 401 signed_out. ~/.t3/userdata/clerk-tokens.json is never created. So on a keyring-less Linux session the desktop app can't sign in at all, with no hint of the actual cause.

    Environment: CachyOS (Arch), Hyprland/Wayland, AppImage 0.0.32-nightly.20260803.986, Electron 41.5.0, @clerk/electron 0.0.24. No gnome-keyring; no org.freedesktop.secrets owner.

    Two additions to the workaround notes in this thread:

    • --password-store=kwallet6 also works, not just gnome-libsecret — kwalletd6 is D-Bus-activated on demand, so on a system with the kwallet package this needs no daemon setup, just creating a wallet on first use.
    • For AppImageLauncher users the flag can't live in the generated desktop entry (regenerated on every nightly); a user-owned wrapper script that globs the newest AppImage and appends the switch survives updates.

    Given this now blocks sign-in (not just environment credential persistence), +1 to shipping a default password-store selection on Linux — and independently, the sign-in path should surface a real "no OS keyring available" error instead of Clerk's raw 401. Happy to send a PR for either.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is broken or behaving incorrectly.needs-triageIssue needs maintainer review and initial categorization.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions