Shipped espanso.service uses WantedBy=default.target, racing the display server at boot (worker panics 101 until X/compositor is up)
Description
The shipped systemd user unit (packaging/linux/usr/lib/systemd/user/espanso.service, installed as /usr/lib/systemd/user/espanso.service) is hooked to WantedBy=default.target:
[Unit]
Description=espanso
[Service]
ExecStart=/usr/bin/espanso launcher
Restart=on-failure
RestartSec=3
[Install]
WantedBy=default.targetdefault.target is reached before the graphical session. On X11 systems espanso talks to Xorg/XWayland via XOpenDisplay, so when the unit starts at boot it races the display server. If X isn't up yet, the worker panics (failed to initialize detector module: detection source initialization failed, espanso/src/cli/worker/engine/mod.rs:146) → daemon exits → launcher panics (espanso/src/cli/launcher/mod.rs:196) → main process exits with status 101 → Restart=on-failure cycles the whole unit every 3 seconds until the display appears. Journal from one boot (4 attempts, ~507ms each):
14:27:30 Started espanso.
14:27:31 [worker(2564)] using X11Source
14:27:31 [worker(2564)] thread 'engine thread' panicked at 'failed to initialize detector module: detection source initialization failed': espanso/src/cli/worker/engine/mod.rs:146
14:27:31 systemd: Main process exited, code=exited, status=101/n/a
14:27:34 restart → same panic
14:27:38 restart → same panic
14:27:41 restart → OK (display finally up)On AppImage installs this restart cycle has an extra cost: each failed start leaves a dead FUSE mount at /tmp/.mount_espans* (see #2791 for that mechanism).
The fix is one line in the unit: WantedBy=graphical-session.target (plus After=graphical-session.target in [Unit]), so the unit starts with — and after — the graphical session instead of racing it.
Steps to reproduce
- X11 system, espanso installed with the shipped
espanso.service(as the .deb/AppImage packaging and Arch AUR packages do),WantedBy=default.target. systemctl --user enable espansoand boot the machine.- If the display server takes more than ~a second to come up after
default.target, the unit panics and restarts 2–4 times (journalctl --user -u espansoshowsstatus=101cycles withfailed to initialize detector module).
Expected behavior
espanso should start with the graphical session, not race it: the unit should be wanted by graphical-session.target so XOpenDisplay/compositor connection succeeds on first start.
Screenshots
No screenshot captured.
Logs
Journal excerpt quoted above (full chain visible: using X11Source → engine-thread panic at espanso/src/cli/worker/engine/mod.rs:146 → daemon/launcher 101 → systemd restart).
Your environment
- Public source code: https://github.com/espanso/espanso (v2.4.0)
- Environment name and version (e.g., Rust 1.59.0): N/A (AppImage edition; unit file verified from both the shipped packaging and the installed system)
- Operating system and version (e.g., Ubuntu 20.04.2 LTS): Arch-based (Manjaro v26.1.1, kernel 6.18, systemd 261)
- Espanso version (e.g., 2.1.4-beta): 2.4.0 (espanso-x11-bin AUR, AppImage)
Self-service
- I'd be willing to fix this bug myself.
Source: espanso/espanso