Building Sideprobe

Designing for multilínguemultilingualmultilinguemehrsprachigmultilinguemultilingüemultilingualconversations: why language cannot be a hidden setting

When an early tester had a conversation mangled by a hidden language setting, and an Apple OS budget silently disabled my own app, I had to rethink multilingual product design from the ground up.

Juarez Filho11 min read

In my previous post on making speech recognition pluggable, I shared why language support is personal to me: here in Ireland, my family's conversations bounce daily between Portuguese, English, French, plus Irish. Speech recognition sets the ceiling for everything a live agent can do. If the transcript drops the ball on technical vocabulary or colloquial phrasing, every note and live suggestion built on top of that transcript inherits the failure.

After benchmarking four local engines on the exact same audio, I opened up Sideprobe so anyone could pick their preferred speech recognizer in settings. It felt like a clean technical milestone.

Then reality caught up with me.

Over the past week, two separate breakdowns shattered my assumptions about how language ought to work in software. The first was an early tester whose important conversation transcript became completely unreadable. The second was a silent crash on my own Mac where Apple's speech engine secretly locked up, taking down live transcription and dictation simultaneously.

These failures forced me to confront an uncomfortable truth: language is not a preference you bury in a settings menu. It is an active part of the conversation that must be visible on screen before you speak.

The tester whose conversation was mangled

Shortly after rolling out pluggable engines, an early tester reached out with feedback that made my stomach drop.

He had just completed an important conversation and shared the exported markdown transcript with the other attendee. Within minutes, the partner wrote back saying the transcript was impossible to understand. Words were fractured, technical terms were mangled into phonetically adjacent gibberish, and entire sentences read like surrealist poetry.

The tester regularly switches between two languages: Brazilian Portuguese and English. When I looked at what happened, the root cause was painfully clear:

  • In his previous session, he had tested speech recognition in Brazilian Portuguese.
  • Days later, he joined an important client conversation conducted entirely in English.
  • Because Sideprobe remembered the earlier selection in the background, the engine attempted to transcribe English speech through a Portuguese phonetic model.
The Product Truth

A wrong language setting is not a minor quality degradation. It makes the entire product look completely broken to someone who never even installed it.

If an app only supports a single language, hiding the setting makes sense. The interface stays minimal. But the moment you support multiple languages, hiding the active language behind a settings window turns into a trap.

The tester did not make a mistake. My interface made the mistake by assuming language could remain invisible.

In speech engineering, researchers call this the monolingual by default trap. Recent benchmarks from and the show why traditional voice pipelines collapse in bilingual environments. When systems try to run an external language detector before speech recognition, any mid-sentence language switch triggers severe phonemic confusion. In , switch-point error rates jump past 48 percent because the detector lags behind the speaker, forcing the transition words into the wrong language model.

When my tester spoke English, Sideprobe was still listening through a Portuguese phonetic filter. The transcript was not just accented; it was completely mangled.

When a silent failure broke transcription on my own Mac

While I was still thinking through how to prevent language mismatches, my own daily build of Sideprobe stopped hearing me entirely a few days ago.

I opened a live conversation, pressed record, and watched the transcription window sit completely empty. I tried using desktop dictation. Nothing happened. I opened settings, and the status label showed a quiet message: Preparing speaker model. It stayed there indefinitely. Nothing turned red. No alert appeared. No crash dialogue opened.

Silent Failure

A bug with a clear error is an annoyance. A bug that fails silently, records an empty file, and leaves a user stranded with zero diagnostic context is an engineering failure.

My immediate instinct was to assume a recent software update had broken audio capture. But when I investigated the system, the application logic had not changed at all.

The real roadblock was hidden deep inside the operating system.

When I dug into the background system logs on my Mac, I found the exact culprit:

Stream run failed: Too many allocated locales, 5 maximum.

Apple's speech engine operates on a strict system budget: macOS permits an application to reserve at most five speech languages in memory.

In Apple's modern Speech framework documentation, this ceiling is officially codified under . Apple exposes maximumReservedLocales as the strict budget of language reservations permitted to any single application, alongside reservedLocales to track current allocations. On Apple Silicon, modern speech modules like SpeechAnalyzer and SpeechTranscriber run local neural weights with complete privacy. But to prevent background models from exhausting unified memory and the Neural Engine, the operating system caps each app at exactly five active locale reservations.

Every time I had tested a different language over the preceding couple of weeks, the app had claimed a new spot in the background. Because the app never released unused languages, it quietly filled all five spots: Irish English, Spanish from Spain (tested with voice recordings sent by a friend), standard French, US English, and Brazilian Portuguese.

When I later tested Italian, the system quietly ignored the request. And days later, when I switched my default to British English, the operating system refused to initialize. Because both live conversation listening and desktop dictation shared that same language setting, that single unmanaged ceiling froze both features across the entire app.

Activity journal: testing speech recognition

Six days of local speech testing

Select a day to inspect how background slots accumulated until Day 6 triggered the silent crash.

Day 6: English (en-GB)
United Kingdom • The Crash
Silent lockup

“Switched default back to British English. macOS hit 5-locale ceiling and silently locked up.”

macOS speech error
Stream run failed: Too many allocated locales, 5 maximum.

Looking behind the breakdown

Peeling back the layers of this failure revealed how easily software breaks down when user experience and background operating system limits drift apart.

The first failure was one of communication between layers. The operating system had hit its ceiling and shut down the speech engine, but that message never surfaced to the screen. Instead, the application kept trying to restart the engine in a futile background loop while showing a peaceful status to the user.

The user interface lied by omission. It displayed Preparing speaker model before confirming that the system was actually ready. When the initialization failed, the status never turned red, and the app never offered a recovery path. It simply sat there, giving the impression of quiet preparation while recording dead air.

Then came a second discovery that mattered even more.

When I sat down to design an error report button so people could report crashes with one click, I inspected what a diagnostic file would actually contain. That inspection brought a profound shock: over 70% of the recorded diagnostic lines on my own computer were verbatim transcripts of spoken conversations.

If someone clicked a button to share a bug report, their private client conversations would have been bundled directly into the file. That would have betrayed the fundamental promise of privacy.

When software promises privacy, diagnostic data must work on an absolute allow-list. You do not try to filter out private words after the fact. You ensure that raw transcripts and spoken phrases are physically barred from ever touching diagnostic files. In my redesigned telemetry, only anonymized performance numbers and high-level system codes can ever leave the device. What people say in their rooms stays strictly on their machine.

The redesign: Language Slots

To solve both problems, the silent setting that mangled my tester's conversation and the background cap that crashed my own Mac, Sideprobe is shifting to an explicit architectural pattern: Language Slots.

1. Conscious pre-conversation visibility

Language selection no longer lives solely in settings. Before any recording starts, the active conversation language sits visibly on the Start bar alongside the audio input. If someone only speaks English, the interface remains quiet and compact. But for anyone switching between multiple languages, the active language is front and center before the microphone opens. An accidental language mismatch becomes virtually impossible.

This also meant fixing how languages are represented. In modern platform guidelines from and , national flags are barred as language icons. Flags represent nation-states, not spoken communication. Mapping a Brazilian or Portuguese flag to a language alienates speakers across regions and creates geopolitical friction. In Language Slots, each language is identified using its native autonym in its own script (such as Português do Brasil, Español de España, or English) alongside clean locale tags. Speakers identify their language in their own script immediately, with zero guesswork.

2. Five explicit slots

You have up to five active slots in Settings → Languages. Each slot connects a specific language to a dedicated speech engine. On first launch, Sideprobe reads your Mac's system languages and fills up to five slots automatically. If you need a sixth language, you make a conscious choice to swap out an idle one, releasing system resources cleanly.

This architecture enables hybrid local routing. Running monolithic models like Whisper Large v3 Turbo across every language taxes unified memory bandwidth on fixed thirty-second audio windows. In recent benchmarks, showed that a model using FastConformer subsampling and duration prediction can run in under 500 MB of unified memory at over 400x real-time speed. Language Slots lets you pair fast local streaming engines like Apple SpeechAnalyzer or Parakeet for everyday conversations, while reserving frontier models for specialized technical vocabulary.

3. Load-bearing AI vs. deterministic code

When redesigning how dictation interacts with multiple languages, I set strict boundaries on where AI should be trusted.

If you have two languages enabled and "Enhance transcript with AI" turned on, you can end a spoken note with a natural instruction like "write it in French" or "escreva em português". The local model that already polishes the transcript recognizes the phrase in any tongue without needing a rigid dictionary.

However, accepting that instruction is strictly deterministic: the app only processes the command if the model returns the exact two to eight words that concluded the audio stream. An AI hallucination can never rewrite your text or insert phantom instructions. Meanwhile, the slot manager, the locale release guards, and the diagnostic log scrubbers run on plain, deterministic code. Cheap, reliable logic handles the safety; the LLM handles only the nuanced semantic polish.

The engineering under the hood

For engineers interested in the systems boundary between native macOS audio, Rust orchestration, and diagnostic privacy:

Why automatic eviction is a trap

When engineers and product designers first hear about a five-language limit, the immediate reaction is almost universal: Why force people to manage slots at all? Why not just automatically swap out the least recently used language in the background?

That was my first thought as well. If an app can silently evict an idle language whenever a new one is requested, the interface stays completely minimal.

The reality of Apple's system architecture quickly destroys that illusion.

In computer science, developers instinctively rely on Least Recently Used (LRU) cache replacement: when memory runs low, drop whatever has been idle. But real-world production teardowns on Apple's modern Speech framework reveal why invisible background eviction triggers catastrophic failures:

  • Asset ownership conflicts: In macOS, calling AssetInventory.reserve(locale:) returns a boolean indicating reservation ownership. If a background LRU loop blindly releases the oldest locale, it can tear down a model actively used by another document window or audio pipeline, corrupting active transcription mid-sentence.
  • The cold-start latency cliff: Acoustic neural weights are not small web icons. When an evicted language is requested again, reloading weights from disk can stall the speech daemon for over ten seconds or throw runtime errors. Attempting to keep multiple unmanaged analyzers in memory quickly exhausts unified memory bandwidth and the Neural Engine.
  • Ecosystem teardowns: Production field reports, including teardowns from the , proved that calling release dynamically in the background unregisters underlying model assets system-wide rather than cleanly recycling memory. Teams that attempted automated background eviction routines had to abandon them.

Instead of hiding limits behind fragile automation, dependable desktop software requires workload-aware cache pinning. By making Language Slots an explicit, user-managed budget, Sideprobe keeps your active languages pinned in memory so they are instantly ready when you speak.

When an eviction routine silently deletes a model that a user expects to be ready for their next conversation, the application has broken the user's trust.

By designing Language Slots as an explicit, conscious budget, Sideprobe aligns user intent with system reality. If you want to add a sixth language, you make a conscious choice to remove an idle one. You know exactly what is installed, you know which voice model is running, and you never walk into an important conversation wondering if your speech engine is about to freeze.

The honest reality of building in public

I want to be completely candid: what I have outlined here is the architectural blueprint, not shipped code.

While the five-locale limit and the dangers of automatic background eviction are now proven by community field data, the exact cleanup lifecycle on a signed production build still requires rigorous validation.

My immediate next step is an isolated technical spike to verify how Sideprobe handles intentional, user-directed removals without requiring an application restart. If the operating system refuses to release the slot cleanly even during an explicit removal flow, my architecture will need to adapt. I would rather share that reality openly than write a post pretending everything is simple.

What is non-negotiable right now is error visibility.

While expanding Sideprobe's capabilities over the past month, I focused heavily on building exciting new features and refining transcription quality. In doing so, I did not pay enough attention to the failure states that could render the tool unusable. That stops here. When an OS limit is reached or an audio pipeline falters, the application will never pretend everything is fine. It will state the problem clearly, give the user actionable next steps, and ensure they can reach out for help with complete privacy.

When you are preparing for an important conversation across languages, you cannot afford silent failures or surprise crashes. Sideprobe has to be predictable, honest about its limits, and completely in your control. That is the standard I am building toward.


Currently available on Mac. Windows coming next.

Have you ever had an app fail silently or scramble an important conversation because of a hidden setting? Share your experience below.

What has your experience been with multilingual voice tools?

Had speech recognition scramble a conversation across languages, or had an operating system limit break an app without warning? Share your story:

Juarez Filho

Responses come straight to my personal inbox. I read and reply to each one myself. Or if you'd rather share your thoughts directly with me or chat about Sideprobe, reach out on X (@juarezpaf) or LinkedIn.


P.S. The interactive components built for this journal (including the Language Slots Inspector, benchmark visualizers, and question collectors) will be open-sourced soon for the developer and design community at sideprobe.ai.