Skip to content

[Bug]: Linux/Hyprland desktop exits silently with no crash diagnostics #10911

Description

@Vanir20342222

Before submitting

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

Area

apps/desktop

Steps to reproduce

  1. Launch T3 Code from the desktop under Hyprland/Wayland.
  2. Use the app normally. The exact interaction immediately preceding the failure is unknown.
  3. The desktop window/process disappears; launching T3 Code again restores access.

This was observed once so far and is not yet deterministic.

Expected behavior

The desktop app should remain open. If it has to exit, it should leave a visible error and a useful crash/exit diagnostic.

Actual behavior

The T3 Code desktop process disappeared unexpectedly. The prior app scope started at 2026-09-09 10:55:34 CEST, and the next launch occurred at 11:02:38 CEST. The replacement process is running normally now.

Impact

Major degradation or frequent failure

Version or commit

t3code-bin 0.0.38-1 (installed 2026-09-09 10:34 CEST)

Environment

Arch Linux x86_64, kernel 7.1.9-arch1-2
Hyprland 0.56.2, Wayland
Electron desktop launched with --ozone-platform=wayland
Intel UHD 630 + NVIDIA GeForce GTX 1050 Ti Mobile
Mesa 26.2.1

Logs or stack traces

# journalctl --user
2026-09-09 10:55:34.535443 CEST systemd[953]: Started app-t3code-87926.scope.
2026-09-09 11:02:38.906517 CEST uwsm_app-daemon[1445]: received: app -- gtk-launch t3code.desktop
2026-09-09 11:02:38.906517 CEST uwsm_app-daemon[1445]: sent: exec systemd-run --user --scope --slice=app-graphical.slice '--unit=app-Hyprland-gtk\\x2dlaunch-cf8add58.scope' --description=gtk-launch --quiet --collect --same-dir -- gtk-launch t3code.desktop
2026-09-09 11:02:39.902160 CEST systemd[953]: Started app-t3code-105259.scope.

# systemd scope state for the exited app
Id=app-t3code-87926.scope
ActiveState=inactive
SubState=dead
Result=success

# checks performed
- coredumpctl list: no entry for /usr/lib/t3code/t3code
- no OOM-killer event in the kernel/user journal
- no T3 Code Crashpad dump was present; only Crashpad/client_id existed
- free -h at investigation time: 31 GiB total, 22 GiB available

The available evidence confirms an unexpected process exit/relaunch, but does not identify whether the cause was an application-level exit, Electron/Wayland failure, or another external termination.

Workaround

Relaunching T3 Code restored the app.

Activity

  1. juliusmarminge commented on Sep 9, 2026

    @juliusmarminge
    Member

    Triage

    Confirmed as a real desktop diagnostic gap, and not a duplicate of #10517 or #2216. The mid-session exit itself is still unexplained — one observation, no app-side logs, no crash artifact.

    What this is / is not

    Issue Symptom Process Status
    #10911 (this) Window/process gone mid-session Exited (Result=success) Open
    #10517 Blank window, backend child died at startup Stays alive Open, accepted
    #2216 Window never appears (ready-to-show on Wayland) Stays alive Fixed in #2262

    #4918 (closed, unmerged) is the same user outcome on AppImage relaunch (“quit and never came back”). t3code-bin is an extracted AppImage without $APPIMAGE, and Linux auto-update is disabled unless that env is set, so this is probably not an updater/relaunch miss.

    No open or merged PR fixes a mid-session silent exit under Hyprland/Wayland.

    What the journal actually shows

    app-t3code-87926.scope → inactive/dead, Result=success. That is exit code 0, not SIGSEGV, SIGKILL, or OOM.

    Together with no coredumpctl entry, no OOM, and Crashpad only having client_id, this looks like a clean shutdown or an uncaptured Chromium/Ozone abort, not a dumped native crash.

    What the desktop process does today

    On Linux, last window closed calls app.quit() (DesktopLifecycle window-all-closed). Hyprland closing the surface (killactive, close, or a Wayland protocol error) is enough to make the app disappear with no dialog.

    SIGINT / SIGTERM are treated as a normal quit (quitFromSignal → app.quit()), which also yields Result=success.

    Visible errors are startup-only (whenReady / bootstrap → showErrorBox). Mid-session, there is no terminal UI.

    Crash reporting is effectively off:

    • crashReporter.start() is never called, so Crashpad often leaves only client_id.
    • No uncaughtException / unhandledRejection.
    • No child-process-gone / gpu-process-crashed handlers. render-process-gone only logs and may reload the renderer; it does not keep a dead main process on screen.

    Logging: Effect goes to stdout (Logger.consolePretty) plus ~/.t3/userdata/logs/desktop.trace.ndjson. gtk-launch uses Terminal=false, so stdout never hits the journal. There is no rotating desktop-main.log. Backend child output is ~/.t3/userdata/logs/server-child.log and would not take down the Electron window by itself (#10517).

    Forced --ozone-platform=wayland on Intel UHD 630 + GTX 1050 Ti Mobile is a known Chromium/Electron hazard (wrong GPU, Vulkan/Ozone mismatch, GPU process death). Some of those paths exit 0 and skip Crashpad.

    Likely causes (unconfirmed)

    1. Last window closed → Linux quit-on-last-window (compositor or user).
    2. Ozone/GPU abort on hybrid Wayland that still exits 0.
    3. SIGTERM from the session/uwsm, then our clean signal quit.

    Need traces to tell these apart.

    Suggested next step

    Not starting a crash-reporter or Wayland-GPU change until we have one more data point.

    Please attach, if they still exist:

    1. ~/.t3/userdata/logs/desktop.trace.ndjson from 10:55–11:03 CEST — look for before-quit received, desktop.lifecycle.windowAllClosed, process signal received, main window render process gone.
    2. ~/.t3/userdata/logs/server-child.log for the same window (rules out a child crash-loop).
    3. Whether the window was closed / killactive / Ctrl+Q, or it vanished while focused and idle.
    4. Any Hyprland/NVIDIA/Mesa lines in journalctl --user for that interval (the snippet only has the scope start + relaunch).

    If it happens again:

    ELECTRON_ENABLE_LOGGING=1 ELECTRON_OZONE_PLATFORM_HINT=auto t3code

    Workaround to try: --ozone-platform=x11 (or drop the forced Wayland flag) on this hybrid box.

    If traces show before-quit / windowAllClosed, this is quit-on-last-window and we should log a reason and/or keep the process. If traces just stop, next product work is a real mid-session diagnostic (file log + Crashpad start() + GPU/child-process handlers), related to #10517 but scoped to “the desktop process vanished.”

  2. added
    bugSomething is broken or behaving incorrectly.
    needs more infoInitial triage showed no bug. Awaiting more info
    via-triageFiled through npx t3 triage
    on Sep 9, 2026
  3. Vanir20342222 commented on Sep 9, 2026

    @Vanir20342222
    Author

    AI model: gpt-5.6-luna

    Thanks for the detailed triage. I checked the requested evidence locally and found no sensitive data that should be attached.

    • desktop.trace.ndjson is present, but there is no before-quit, windowAllClosed, signal, renderer-process-gone, or GPU-process-crashed event in the relevant interval.
    • The trace contains the normal startup/window-created sequence after the relaunch, but no corresponding shutdown reason for the previous session.
    • server-child.log is not present. The available server trace shows normal activity around the relaunch and no backend crash or crash-loop.
    • The user journal has the app-scope start and subsequent relaunch, plus unrelated xkbcomp warnings; I found no NVIDIA/Mesa/Wayland/GPU error for that interval.
    • I have no evidence that the window was deliberately closed, killactive/Ctrl+Q was used, or that a GPU abort occurred, so the trigger remains unknown.

    So this still looks like an uncaptured clean exit or compositor/Electron termination, with no local trace that distinguishes those cases. I have not attached the raw logs because they include local environment/project details. I’ll try the --ozone-platform=x11 workaround if it recurs, and will capture a focused trace with logging enabled before relaunching.

  4. kyryl-bogach commented on Sep 17, 2026

    @kyryl-bogach

    Same failure on Arch + Hyprland, on 0.0.42. I have data that narrows this down: the backend child died first, and the desktop shell then quit itself on purpose. The shell is a victim, not the cause.

    Environment

    • t3code-bin 0.0.42-1 (Arch AUR), kernel 7.2.5-3-omarchy
    • Hyprland 0.56.2, Wayland, launched with --ozone-platform=wayland
    • AMD Ryzen 9 5900X (24 threads), NVIDIA RTX 5080
    • 62 GiB RAM, 125 GiB swap. 38 GiB available at the time.

    Incident

    Session started 2026-09-17 09:23:33 CEST, died 09:40:20 CEST. No user action, an agent run was streaming.

    ~/.t3/userdata/logs/desktop.trace.ndjson holds the cause. The span for runBackendProcess, opened at session start, closes with:

    runBackendProcess | Failure
    BackendProcessExitStatusError: Failed to read the exit status of desktop backend process 9150.
        at .../apps/desktop/dist-electron/main.cjs:110323:67
        at .../apps/desktop/dist-electron/main.cjs:4245:91
        at ~effect/Utils/internal (.../main.cjs:1464:11)
        at runBackendProcess (.../main.cjs:110509:19)
        at runBackendProcess (definition) (.../main.cjs:110247:27)
        at desktop.backendInstance.start (.../main.cjs:110550:12)
    

    The shell then ran an orderly shutdown, which is why systemd sees a clean exit and why there is no crash artifact:

    09:40:18  desktop.window.handleBackendNotReady   Success
    09:40:18  desktop.lifecycle.windowAllClosed      Success
    09:40:18  desktop.lifecycle.beforeQuit           Success
    09:40:18  desktop.lifecycle.requestShutdownAndWait  Success
    09:40:18  desktop.app.stopAllPoolInstances       Success
    09:40:18  desktop.backendInstance.stop           Success
    09:40:20  desktop.backendInstance.finalizeRun    Success
    09:40:20  PreviewManager.destroy                 Success
    

    The backend leaves no error of its own

    server.trace.ndjson stops dead at 09:39:28, roughly 50 seconds before the shell gives up. The last line is a normal handleSdkMessage span with "exit":{"_tag":"Success"}. There is no error record, no shutdown span, nothing. The process had no chance to write one.

    Workload in its final 90 seconds, by span name:

        901  updateResumeCursor
        883  ensureThreadId
        883  handleSdkMessage
        825  handleStreamEvent
        812  sql.execute
        131  sql.transaction
         90  ProjectionSnapshotQuery.getThreadRuntimeContext
         87  PortDiscovery.registerTerminalProcesses
         64  applyThreadMessagesProjection
         64  applyThreadsProjection
         64  applyThreadTurnsProjection
         64  applyThreadActivitiesProjection
         64  applyThreadSessionsProjection
         64  applyThreadProposedPlansProjection
         64  applyPendingApprovalsProjection
         64  applyProjectsProjection
         64  decideOrchestrationCommand
    

    883 SDK messages in 90 seconds, each driving a SQLite write plus a full rebuild of eight projections. Provider was claudeAgent on a long-running thread.

    systemd accounting

    app-com.t3tools.T3Code-8984.scope: Consumed 24min 41.687s CPU time
    over 16min 47.416s wall clock time, 25.6G memory peak.
    

    Caveat on that number: cgroup memory.peak counts page cache, so it overstates real usage. In the session that followed I measured MemoryPeak=5.7G against MemoryCurrent=544M, with about 1.3 GB of actual process RSS. So 25.6 G is not by itself proof of a leak. The CPU figure is solid: about 1.5 cores sustained for 17 minutes.

    Causes ruled out

    • Kernel OOM killer: no event. 38 GiB was available.
    • systemd-oomd (the mechanism in [Bug]: systemd-oomd kills the entire T3 Code scope when an agent-spawned child workload exhausts memory (Linux) #5248): active and enabled on this machine, logged no kill. app-graphical.slice has MemoryHigh=infinity and MemoryMax=infinity, so no cgroup limit applied.
    • Core dump: none. coredumpctl has no entry for t3code. An unrelated Node OOM on this machine two days earlier did produce a dump, so core dumps do work here. Electron's own handler suppresses them for t3code.
    • Crashpad: no report. ~/.config/t3code/Crashpad/ holds only client_id.
    • Hardware: no MCE or ECC errors, no NVMe or filesystem I/O errors in 7 days.
    • Package upgrade: ruled out. A separate app exit on 2026-09-16 at 21:39:49 turned out to be pacman upgrading 0.0.40-1 to 0.0.42-1 eighteen seconds earlier. Worth knowing when reading Linux reports: an in-place upgrade looks identical to a silent crash in the journal.

    What is still unknown

    Whether the backend hit the V8 heap cap, took a native crash, or was killed. Nothing on this machine records it.

    Two things would close that gap:

    1. The backend should log its own death. Right now an abrupt exit produces zero diagnostics on either side. BackendProcessExitStatusError says the parent could not even read the exit status, which is its own bug.
    2. Surface the child's stderr. A V8 abort prints FATAL ERROR: ... JavaScript heap out of memory to stderr and nowhere else. Neither trace log captures it, so it is lost unless the app is started from a terminal. I am running that way now and will report back if it reproduces.

    Trace excerpts

    https://gist.github.com/kyryl-bogach/9d260d7ba4c1c98d12b7489176feaf9d

    • server-final-120s.ndjson - the backend's last 120 seconds. The file ends where the process died, mid stream, with no error record.
    • desktop-shutdown.ndjson - the detection and shutdown, including the runBackendProcess Failure span.

    These are rebuilt from a field allowlist rather than scrubbed, so nothing outside the allowlist can appear. The gist README lists exactly what is kept and what is dropped.

    Two things I had to drop are worth naming. git.cwd carries absolute paths to private repositories. url.full carries a wsTicket bearer token in plain text, 31 times in one rotated file. A credential written unredacted into local trace logs may deserve its own issue.

    Happy to supply more on request.

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 more infoInitial triage showed no bug. Awaiting more infovia-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions