Troubleshooting¶
Start here: prove where it breaks¶
Before reading further, let YazSes tell you which part is broken:
It reports each link in the chain and stops at the first failure, so you get the one thing to fix rather than four symptoms of it. yazses doctor complements it by checking prerequisites — a mic exists, the injector is installed, the model is cached — but every one of those can pass while dictation still produces nothing, which is why verify exists.
If you want to report a problem, yazses report writes a diagnostic file locally — versions, daemon state, settings with paths and identifiers removed, and the metadata-only log tail. Your dictated text is never in it, and nothing is uploaded; the file is yours to read before deciding to attach it to an issue.
YazSes usually tells you first¶
Most failures now announce themselves as a desktop notification that names the cause and the command that fixes it — a microphone another program has taken, a missing ydotool, a full disk. So the first thing to do is read the message rather than start here.
Two details worth knowing:
- The same problem is announced once every five minutes, not once per attempt. A microphone that will not open fails on every burst, and repeat toasts would only teach you to dismiss them. The state is still in
yazses statusand the tray tooltip throughout. - When YazSes cannot work out what went wrong, the notification carries a Prepare a bug report button. It assembles the same redacted bundle
yazses reportwrites and opens GitHub's issue form with it filled in — you read it there, in your own browser and account, and press submit yourself. YazSes sends nothing; the browser makes the request. A failure YazSes does recognise gets no button, because it already told you the fix.
Some of this fixes itself — check before you debug
A microphone that was stolen mid-session, a silence gate that drifted above your voice, a crashed daemon and a crashed tray all recover on their own, and each says so when it happens. If you are about to debug one of those, read what recovers by itself, and what does not first — it also lists the failures that are deliberately left for you, so you can tell which kind you are looking at.
The app opened and nothing happened for minutes¶
Symptom. You started YazSes for the first time and holding the hotkey does nothing. Either nothing seems to happen at all, or the tray icon is there but only shows that it is loading.
First, check what you started. Not every launcher starts dictation:
yazses start(any platform) starts the daemon, and the daemon downloads the model.- The macOS app (installed from the
.dmg) and the Windows YazSes shortcut (Start menu, desktop, or the installer's Launch YazSes now) open the tray, and the tray starts the daemon. The tray icon appears at once and shows the loading state while the model downloads. - The Linux app-grid entry and the Windows YazSes Settings shortcut open only the Settings window. Settings does not start the daemon, so no download begins and waiting will not help. Run
yazses start(oryazses tray) to start dictation.
Why. The first start downloads the speech model (base.en unless you chose another). The daemon fetches it before it starts listening for the hotkey, so the key does nothing until the download is done. This is the one step that needs the network.
Fix. Usually, just wait. To see what it is doing:
- The download notice. When the model is not on disk yet, YazSes shows a notification titled YazSes is downloading its speech model. It does not show one when the model is already cached or when you asked for offline mode.
yazses status. While the model is fetched it printsstate: loading. Before the daemon can answer at all it says the daemon is running … but still starting up.state: idlemeans you can dictate.- The tray. A tray that is already running shows the
loadingstate in its tooltip or menu (⏳ in the macOS menu bar). Otherwise the daemon starts the tray icon only once the model has loaded, so the icon appearing is your cue that dictation works. No separate "ready" notification is sent.
If the download fails (a firewall, a proxy, no network), the wait ends in an error instead. A notification titled YazSes cannot start dictation says The speech model '…' is missing and could not be downloaded, yazses status shows state: error, and a tray that is already running turns red (⚠️ in the macOS menu bar). The message names the two commands that fix it:
To skip the wait on a new machine, run yazses model download base.en (or your model) before the first start. yazses doctor names this in its STT model row (not downloaded — fetched automatically the first time the daemon starts). For a machine that is never online, see running fully air-gapped.
My desktop asked to allow "Remote Desktop" — why does a dictation app want that?¶
Because on Wayland there is no narrower permission to ask for. RemoteDesktop is the only portal interface that lets one application type into another's window, so every tool that types on your behalf — dictation, accessibility software, automation — goes through the same door, and inherits the name it was given for its original purpose, screen sharing. The confirm button says Share for the same reason.
What YazSes actually requests is the keyboard, and nothing else unless you ask for it:
- it asks the portal for
KEYBOARDdevices only — the pointer is added to the same request only while a pointer feature you turned on (the head pointer) needs it, and the dialog wording says so; - it never touches the ScreenCast interface, so no screen capture is possible with it;
- the calls are local D-Bus to your own desktop — no network, consistent with YazSes being offline by design.
Your top bar will show a screen-sharing indicator the whole time the daemon runs. That is your desktop reporting that a RemoteDesktop session is open; it cannot tell that the session was granted the keyboard alone, so it shows its generic icon. It is not evidence that anything is being captured or sent.
You are asked once — the answer is remembered with a restore token stored at ~/.local/share/yazses/portal_remote_desktop_token (mode 0600). Delete that file to be asked again.
Getting rid of the prompt entirely¶
The portal is a fallback. YazSes prefers ydotool, which injects directly and needs no permission dialog, and only falls through to the portal when ydotoold is not running.
Two things have to be true for ydotool to work, and on a stock Ubuntu neither is by default — which is why most Wayland users land on the portal:
- the
ydotoolddaemon must be installed. On Debian/Ubuntu it is a separate package from theydotoolclient, so installingydotoolalone leaves the service pointing at a binary that does not exist; /dev/uinputmust be openable by your user. It ships0600 root:root, so belonging to theinputgroup grants nothing without a udev rule.
yazses setup now does both:
yazses setup # installs ydotoold + the /dev/uinput udev rule, joins `input`
# log out and back in — the group and the rule only apply to a new session
yazses doctor # the Injection line names the backend actually in use
The log-out is not optional. Until you start a new session the rule has not reached it, ydotoold still cannot open the device, and YazSes will keep using the portal.
The exception is the strictly confined snap, which has no package manager and cannot install a udev rule — there the portal is genuinely the only way to type on Wayland, and yazses setup is not offered.
If you declined the dialog, dictation falls back to pasting via the clipboard, which is a no-op in terminals. Approve it, or run yazses setup, then yazses restart.
yazses start says it started, but yazses status says "not running"¶
YazSes now tells you why instead of printing a hopeful "still loading". If no daemon process appears, yazses start reads the systemd unit and its journal and prints the cause with the exact commands to copy — for example a unit whose program does not exist (a packaged unit next to a pipx install), a crash loop systemd gave up on, a missing system library (with the package name for your distribution), or an unreadable /dev/input. yazses doctor shows the same thing under Service health.
The two fixes behind most cases:
yazses autostart enable # rewrite the unit to the install you run
systemctl --user reset-failed yazses.service # clear "start request repeated too quickly"
Dictation is heard and "typed", but nothing appears (GNOME Wayland)¶
Symptom. You hold the hotkey, speak, release — and nothing appears. Yet yazses doctor says everything is fine, yazses status reports the burst as "typed", and the log shows Injecting N chars.
Cause. The voice-activity overlay is a separate window that appears the moment you press the hotkey. On native Wayland (Ubuntu's default GNOME session) the compositor gives every new window keyboard focus, and an application cannot opt out of that. Focus moves from your text field to the overlay, and the dictated text is typed into the overlay instead of your app. yazses status counts injections, not text that arrived, so it cannot see this.
Fix. Turn the overlay off, then restart:
Or set it in ~/.config/yazses/config.toml and restart:
The overlay is optional and off by default in current releases, and a build that includes the Wayland guard never starts it on a native Wayland session unless you set QT_QPA_PLATFORM yourself. Builds up to and including 2.40.1 do not have that guard and started the overlay by default, so they are affected. After the restart, confirm with pgrep -af yazses-overlay — it should print nothing.
Still nothing typed with the overlay off? Ask YazSes to prove that typing arrives, not merely that it was sent:
It records a few seconds, transcribes, then types the result into a small window it opens and checks the text arrived there. The Delivery line is evidence, where doctor and status only describe the sender:
| Result | What it means |
|---|---|
[OK] Delivery: typed N characters and they arrived | Typing reaches a focused window on this machine. If your own app still gets nothing, the cause is that app or something taking focus from it. |
[FAIL] Delivery: … nothing arrived | The keystrokes leave YazSes and are not delivered. On Linux with ydotool, YazSes restarts the ydotoold user service once and tries again, and says if that helped. |
[FAIL] Delivery: … received "…" | Something arrived but not what was typed: a keyboard-layout mismatch or dropped keys. Restarting does not fix that, so none is attempted. |
[FAIL] Delivery: not proven — … | The check window never got keyboard focus, so nothing was typed and nothing can be said. It is never reported as a pass. |
Without the desktop extra (PySide6) or a graphical session there is no check window; the command says so and falls back to typing into the focused window, with arrival not checked.
It works, but not after I reboot¶
YazSes is a daemon, so it should already be running when you sit down:
yazses autostart status # will it come back after the next reboot?
yazses autostart enable # make it
Installing with pipx, uv tool or pip does not set this up on its own. yazses doctor reports it as a Starts at login check.
Dictation stopped working right after I edited config.toml¶
If every hold is accepted but no text ever appears, read the log first:
A line like this means the pipeline threw an exception on every burst:
WARNING yazses.core.daemon: Pipeline error: ufunc 'less' did not contain a loop
with signature matching types (Float32DType, StrDType) -> None
Float32DType is your audio, StrDType is a config value that should have been a number. The usual cause is a quoted number in config.toml:
[accessibility]
vad_threshold = "0.004" # wrong — this is a string
vad_threshold = 0.004 # right — bare number
In TOML, only string values take quotes. Numbers (int, float) and booleans must be bare, and the Configuration Reference lists the expected type for every key. A quoted number loads without any error and only fails later, deep in the pipeline, so the message never mentions the file you edited.
The safe way to change a setting is to let YazSes write it, since these commands always emit the right type:
yazses features enable <name> # feature toggles
yazses hotkey set right_ctrl # hold-to-talk key
yazses audio use "<mic name>" # input device
yazses mic-level --set # measure and write vad_threshold
Dictation still works, but it behaves differently than it used to¶
Every setting that affects the pipeline is announced when the daemon starts, so the log is an accurate record of what was actually in effect — including on previous days.
A healthy start looks roughly like this. Each line reflects a config value, so a line that is present, missing, or different from what you remember tells you exactly which setting changed:
Loading STT model 'base.en'... ← [stt] model
Injection backend: XdotoolInjector ← [injection] backend
Streaming STT enabled (partial …) ← [streaming] enabled (absent when off)
Command key enabled: hold right_alt … ← [hotkey] command_key (absent when unset)
YazSes ready. Hold right_ctrl to dictate. ← [hotkey] key
Launched voice-activity overlay … ← [overlay] enabled
To compare against a day when it behaved the way you wanted, look at the rotated log, which keeps the previous startups:
grep -h "YazSes ready\|Streaming STT\|Command key\|Loading STT model" \
~/.local/state/yazses/log/daemon.log.1 ~/.local/state/yazses/log/daemon.log
Two settings are worth checking first, because both change how dictation feels without ever producing an error:
[streaming] enabled = trueruns a transcription pass every 300 ms during the hold, on top of the final one. On a CPU-only machine that competes with the transcription that actually produces your text. It is off by default for this reason.[accessibility] vad_thresholddecides what counts as silence. Too high and quiet speech is dropped withSilent audio -- discarding; too low and room noise is transcribed. It is specific to your microphone and room — runyazses mic-level --setrather than copying a value from someone else.
A feature is on, but it does nothing (◐ ON)¶
Some capabilities need an optional library (Parakeet needs onnx-asr, noise suppression needs noisereduce, the camera features need mediapipe). If the capability is switched on but its library is missing, yazses features shows it as ◐ ON, and the daemon says so when it starts. This happens when the install failed, when you used --no-install, when you edited config.toml by hand, or when an older version's update removed the library. The daemon's notification has an Install now button, and yazses start/restart offer the install in a terminal. Or install every one in a single step — it shows the download and asks first:
yazses features repair does the same for all of them and ends with one line per feature saying whether it was installed. yazses features repair --dry-run only lists what is dormant and what each needs, and installs nothing.
yazses features enable <name> (add --force for an experimental one) does the same for one feature and is safe to run again. If an install fails part-way or you press Ctrl-C, whatever it had changed is undone, and an install that would move one of YazSes's own libraries (numpy, say) out of range is refused before anything changes.
yazses doctor prints one row for each such feature. Updating with yazses update or the tray's Install update keeps the libraries of every feature that works, including ones an older version installed (only the uv tool install method ever dropped them).
YazSes typed a sentence I never said¶
Speech models do not return "I heard nothing". Given near-silence they return their best guess at what a person would have said, and that guess is ordinary, fluent English — not gibberish you could spot. YazSes filters the recognisable cases (a blank marker, a caption artefact, a phrase repeating in a loop) but an invented sentence is indistinguishable from a real one to everything except you.
What makes it happen is a silence gate set below your room, so the noise floor is treated as speech and sent to be transcribed. Check it:
If the Signal line ends with "but only just" and a multiple close to 1, that is the cause. Your voice should sit several times above the gate; noise sits just over it.
To check the gate against the room alone, without speaking:
It records two seconds of your room on the microphone YazSes uses ([audio] device when you have pinned one) and reports [WARN] Mic level: ambient … >= vad_threshold … when the room alone already clears the gate. Plain yazses doctor never opens the microphone, so it cannot tell you this.
Then run yazses verify again in a quiet room without speaking. The outcome you want is verify failing at either Signal or Speech — the model being given nothing is the only reliable way to stop it inventing. Speech is the one that fires when room noise clears the gate: it runs a speech detector on what was actually recorded, so a quiet room is named as a quiet room rather than transcribed into a confident word.
Since v2.43.2 the daemon also asks a speech detector about every burst that clears the gate, before it is decoded. A burst that is loud but holds no speech (a fan, a chair, the hotkey itself) is discarded with a line like No speech in a 1.2s burst (level 0.0300 cleared vad_threshold 0.0100, but the speech detector found none) -- discarding. Without that, the model answers such a burst with the words it was primed with: the built-in name vocabulary came back as the sentence "The app is called YazSes." in every no-speech test run with the real model. The log line carries numbers only, never audio or text. The check is skipped in Whisper / Low-Effort mode, Dysfluency-Friendly mode and the sotto-voce command channel, and does nothing when the detector cannot run. Whispering is the weak spot: in a test with a crude whisper stand-in about one word in seven was judged to hold no speech at normal volume. If quiet or whispered speech is being discarded as "no speech", set [accessibility] speech_presence_check = false.
Raising the gate too far has the opposite failure and it is the visible one: quiet speech is dropped with Silent audio -- discarding in yazses logs. That is why the automatic tuner only ever lowers the gate — a mic that hears too little tells you so, and a mic that hears too much does not.
Windows: one app gets ???? or ---- where the words should be¶
The giveaway is that it is one application. The same dictation lands correctly in a browser and arrives in an editor or a notes app as the right number of characters with every one of them wrong — rows of ?, - or ..
Nothing is wrong with the transcript. YazSes types on Windows with SendInput and the KEYEVENTF_UNICODE flag, and Microsoft documents two ways an application can receive that keystroke incorrectly:
- An ANSI window. Windows converts each character to the application's ANSI codepage on the way in and substitutes
?for anything that codepage cannot represent. - A text service that does not unpack
VK_PACKET.KEYEVENTF_UNICODEsynthesises a VK_PACKET keystroke that carries the character as data. A text input service that does not read it out runs the keystroke through your keyboard layout instead, so the whole sentence comes out as the same wrong character repeated.
Chromium handles VK_PACKET explicitly, which is why the browser is always fine.
Find out which window you are really typing into:
You then have five seconds to click into the application under test. It reports the focused control, whether it is a Unicode window, and your active keyboard layout, and then types. If the text is mangled there too, the application is the cause. If it is clean there but dictation is not, the problem is in the hold-to-talk path, not the injector — say so in an issue.
The fix is to paste rather than type, which depends on neither condition:
The transcript goes on the clipboard as Unicode text and YazSes sends a real Ctrl+V. Your previous clipboard contents are put back afterwards. Two trade-offs come with it, and they are why typing remains the default: Ctrl+V is literal in most terminals, so dictation into a terminal stops working, and applications that refuse paste (some password fields) receive nothing.
Dictation stops after connecting a USB-C monitor or headset¶
Some monitors, docks, and headsets register an audio input and become the operating system's default microphone. When that input is silent or very quiet, YazSes can keep running but stop writing dictated text because each recording is discarded as silence.
Check which device YazSes is using:
The mic-change guard normally detects a default-input change and switches back to the last working microphone. To prevent the operating system from changing the capture device again, pin the intended microphone using a case-insensitive part of its displayed name, then restart YazSes:
Run yazses audio status again to confirm that the pinned microphone is active. To return to following the operating system default later, run: