engine internals
Troubleshooting
Common stuck-points and the fix for each. If something here doesn't match your symptoms, ask in Discord — most issues end up in this list once they happen twice.
"wflow doctor says wdotool is missing"
wdotool is wflow's keystroke-injection backend on Wayland. Most distros don't include it.
# Arch:
yay -S wdotool
# Fedora / Debian / Ubuntu:
# wdotool isn't packaged yet on most distros — build from source:
git clone https://github.com/cushycush/wdotool
cd wdotool
cargo build --release
sudo install -m 0755 target/release/wdotool /usr/local/bin/wdotoolVerify: which wdotool should print a path, wdotool --version should report a version.
"My chord doesn't fire"
Diagnose in this order:
- Daemon running?
systemctl --user status wflow-daemonorpgrep -fa "wflow daemon". If not: start it (see Daemon & systemd). - Workflow loaded? Check
journalctl --user -u wflow-daemon -n 50for parse errors at startup or after the most recent file change. The daemon's file watcher reacts in real time; fix the file and the daemon re-binds without a restart (compositor-IPC mode) or after one restart (portal mode). - Chord taken? Most compositors reserve chunks of the chord namespace for window management. Try a different chord. If you're on KDE Plasma 6 / GNOME 46+, the GlobalShortcuts portal will show the conflict in the system shortcut panel; on Hyprland, look for a duplicate
bindline. - Backend reachable?
wflow doctorreports the active compositor and which backend the daemon will pick. The daemon's first log line names the backend it ended up using.
"Open in wflow doesn't open wflow"
The browser's scheme handler isn't registered. See the wflow:// protocol page for the full registration steps. TL;DR:
xdg-mime query default x-scheme-handler/wflow
# expect: io.github.cushycush.wflow.desktop
# If not:
xdg-mime default io.github.cushycush.wflow.desktop x-scheme-handler/wflow
update-desktop-database ~/.local/share/applicationsRe-launching the wflow GUI once also rewrites the desktop file from scratch — useful after a binary path change.
"Workflow runs but at unexpected speed"
Two knobs:
- Per-step
delay-msontypesteps bumps the inter-keystroke delay for laggy apps. - Explicit
waitsteps between actions that need the previous one to settle. Afocusfollowed bytypealmost always wantswait 300in between, otherwise the early keystrokes go to the wrong window.
Reminder: wait takes integer milliseconds, or a duration string ("1.5s", "500ms", "2m").
"Shell step times out / fails silently"
By default shell has no timeout. If you set timeout-ms and the command exceeds it, the child is killed and the step errors. Long-running commands either need a higher timeout or none at all:
shell "long-running-thing" timeout-ms=60000For commands that legitimately fail sometimes, set on-error=continue so the workflow proceeds anyway:
shell "git push" on-error=continue
notify "tried to push (best effort)""How do I see what wflow's actually doing?"
wflow uses tracing via the standard RUST_LOG env var:
RUST_LOG=wflow=debug wflow daemon
RUST_LOG=wflow=trace wflow run my-workflowEvery trigger fire, every step, every shell exit code logs to stderr. Helpful when the symptom is "the workflow ran but didn't do what I expected." For the systemd unit, set the env var via a drop-in (see Daemon & systemd).
"My library has a workflow that won't load"
journalctl --user -u wflow-daemon -n 50 shows the parse error with a line number. Common causes:
- Filename mismatch.
store::load(id)needs filename ==safe_id(id).kdl. If you renamed the workflow inside KDL but the filename still has the old slug, loading by id silently fails. Either rename the file or runwflow migrate. - Stray
include ""from a pre-1.0 file with an empty include directive — drop the line. - Unknown action kind. The parser lists the valid kinds in the error message.
If you're still stuck
Ask in Discord with:
- The workflow KDL
- The output of
wflow doctor - The relevant 10 lines from
journalctl --user -u wflow-daemon - Your compositor (Plasma, GNOME, Hyprland, Sway, ...) and version