We let people bring their own AI key: Gemini, OpenAI, or Anthropic. Connect one, and features across the app that use AI (things like drafting a client update or summarizing a task thread) start using it.
There was also a "default provider" switch on the settings page. It had been there a while. It did nothing.
Here's why.
The bug
Every AI feature in the codebase called AI the same way most codebases end up doing it: reach for the key it already knew about.
The switch on the settings page wrote to active_ai_provider. Nothing ever read it. A workspace with only an OpenAI key got silence from every AI feature, because the only code path anyone had wired up looked for a Gemini key specifically.
It gets worse in one specific place. A client-insight report feature had its own logic for picking a provider, hardcoded in a different order than anywhere else. Two sources of truth for the same decision, neither reading the setting meant to control it.
The fix — one resolution function, every caller goes through it now, with real code (resolveAiProvider + callAi, quoted byte-for-byte with the original comments).
Why this kind of bug is easy to ship — nothing threw an error, nothing failed loudly, so it never filed itself as an incident.
Closes with: "We build Melororium, a flat-fee workspace for small teams, this is one of the smaller pieces of it. If you want to see the rest, the demo's open, no card required: https://melororium.com"













