fundamentals
Why dictation misspells the names you added to it
A custom dictionary usually just whispers a hint to the model, and models are free to ignore hints. What it actually takes to make a name spell right, every time.
Every dictation app has a custom dictionary. You add your company, your colleagues, the library you work in every day. And then it keeps spelling them wrong, and you conclude the feature is broken.
The feature is not broken. It is usually doing exactly what it was built to do, and what it was built to do is ask nicely.
A dictionary is usually a hint, and a hint is not an instruction
Here is the mechanism behind almost every custom-vocabulary setting.
Before transcription runs, your dictionary terms are passed to the speech model as a prompt — a short
preamble that says, in effect, words like these are likely to come up. If you have ever used a
Whisper-style API directly, this is the initial_prompt parameter, and a custom-vocabulary setting is
usually a text field wired to it. The model takes that as context. It is genuinely useful, and it is
genuinely optional, because a model conditioned on a hint is under no obligation to act on it.
Two things go wrong in practice, and they go wrong in different places.
Fast models discount the hint. The small, quick transcription models — the ones a hold-to-talk app wants, because you are waiting on the result — are the ones most likely to sail straight past your preamble and produce the common spelling anyway. The faster the model, the weaker the hint.
On-device engines often cannot take a hint at all. Local transcription is a different code path with different constraints. In Halopen’s case, prompt-biasing is switched off entirely on the on-device path, because feeding it a term list degraded decoding quality on the large model — the hint made the transcript worse. So on the private path, the dictionary had no mechanism whatsoever.
Which produced the specific bug that started this. A café called Meria came back as Maria every single time, no matter how many times it was added to the dictionary. The setting was on, the term was there, and the word was wrong — on the cloud path because the model discounted the hint, and on the local path because there was no hint to discount.
The fix has to run after the model, not before it
If you cannot rely on the model cooperating, stop asking it to.
Halopen keeps the prompt-biasing where it helps, and then adds a second mechanism on the other side: after the transcript comes back, a deterministic pass rewrites near-homophone misspellings of your dictionary phrases to your exact spelling. “Cafe Maria” becomes “Cafe Meria,” because “Cafe Meria” is in your dictionary and the transcript is one letter away from it.
Four properties matter more than the idea itself.
It is deterministic. Same input, same output, every time. No second model, no judgment call, no new opportunity for something to be creative with your words.
It runs offline, client-side, on both paths. It never needed a network, so it fixes the on-device transcript and the cloud transcript identically. The private path stops being the one where your dictionary quietly does nothing.
It runs before the rest of the pipeline. The correction lands before snippet expansion, so a corrected term can still trigger a snippet you defined. And it lands before any cleanup pass, so the cleanup model sees the right spelling and carries it through rather than helpfully un-correcting it back to the common word.
It is gated on the same switch. Turn the dictionary off and both mechanisms stop. One toggle, one mental model, no surprise behaviour left running underneath.
The hard part is refusing
A corrector that fixes names is easy. A corrector that fixes names and hardly ever touches a word you meant is the whole engineering problem, because the failure mode is horrible. A message about your friend Maria has to still say Maria — an app that gets that wrong is not misspelling a word, it is rewriting a person.
So the thing is built to refuse. Two structural guards, both of which cost recall on purpose.
Only multi-word entries participate. A single-word dictionary entry is never homophone-corrected. A lone token carries no surrounding context to disambiguate intent, and common-word entries would wreck ordinary prose — imagine a dictionary containing “Composed” quietly rewriting every use of the ordinary adjective. Single words are left to the prompt-bias path, where the cost of a miss is a misspelling rather than a corruption.
Every match needs an exact anchor. A phrase matches a stretch of transcript only when at least one of its words matches exactly — the “Cafe” in “Cafe Meria” — while every other word sits at most a tight edit distance away, and at least one word actually differs so there is something to fix. No anchor, no match. Loose resemblance, no match. Nothing to fix, no touch.
The result is a tool that misses corrections it could plausibly have made. That is the correct trade. A missed correction is a typo you fix in two seconds; a wrong correction is your software putting words in your mouth, which is the one thing a verbatim dictation app must never do.
What the multi-word rule buys is narrower than “it never gets it wrong,” and worth stating exactly. A single name on its own is never rewritten, so an ordinary Maria in an ordinary sentence is safe no matter what your dictionary holds. But if you added the phrase “Cafe Meria” and you then genuinely mean a different Cafe Maria, that one will be corrected — you claimed the phrase, and the corrector takes you at your word. The protection is against collateral damage to words you never claimed, not against the consequences of your own dictionary.
What to check in whatever you use
Three minutes, and it works on any dictation tool.
- Add a two-word proper noun that has a common near-homophone — a name, a brand, a place your autocorrect already fights you about. Dictate a sentence containing it.
- Then do it again in the private or offline mode, if your tool has one. This is where dictionary support most often silently disappears, because it is a separate code path with different limits, and nothing in the interface tells you the setting stopped applying.
- Then dictate a sentence with the near-homophone you did not add — a genuine “Maria” when “Meria” is your dictionary term. If it gets rewritten, the tool is over-correcting, and that is a worse problem than the one it solved.
A dictionary that survives all three is doing real work. One that only passes the first is asking the model nicely and hoping, which is what most of them are doing, and which is why you are still fixing the same name by hand.
Halopen is native macOS dictation, verbatim by default, with a dictionary that works on the offline path too. Try the time-limited no-card trial — halopen.com.
Try Halopen
Hold the function key. Speak.
Halopen is free for 14 days, no credit card. Pro is $19/mo or $179/yr — unlimited.
Read next
More from Halopen Learn
-
fundamentals
Why your dictation app rewrites what you said
Most dictation runs a silent cleanup pass after transcription. It is usually helpful, and it quietly costs you the words you actually chose.
-
privacy
The Halopen audit log: what it is and how to read it
Read Halopen’s local transcript and event log, recover a draft, control retention, and understand what the log cannot prove about network activity.
-
privacy
What on-device dictation means in Halopen
Understand local speech recognition on Apple Silicon, model setup, local history and the network activity that remains separate.
-
privacy
Offline dictation on a Mac: what works without internet
Dictate on an Apple Silicon Mac with no connection once setup is done. What needs internet and when, what changes offline, requirements and plans.