When a help key is missing
Your component asks for a help key and nothing comes back. That will happen: the key was never written, the topic is still a draft, someone withdrew it, or the deploy went out ahead of the content. What your application does in that second is a design decision, and most products make it by accident.
This page sets out the cases, the answer for each, and how the usual tools behave.
The cases are not the same thing
The key was never written. Your code asks for billing.invoice.explained and no topic claims it. Nobody made a mistake; the sentence has not been written yet. Our delivery API answers 404 with the code KEY_NOT_FOUND.
The topic exists but is not published. Someone is writing it right now. That is a different situation with a different owner, so it gets its own code: 404 with NOT_PUBLISHED. The user sees the same nothing, and your logs can tell the two apart, which is the point.
It was published and then withdrawn. From the moment of withdrawal, the address answers exactly as the previous case. Removing help is as immediate as publishing it.
The collection is wrong. A staging id in a production build, a copied environment variable, a typo. You get COLLECTION_NOT_FOUND, and the useful part is that it is not KEY_NOT_FOUND: one broken configuration does not look like four hundred missing texts.
Two topics claim one key. Publishing refuses the second claim, so this should not arise. If the delivery layer ever sees it anyway, it answers 409 with AMBIGUOUS_KEY and names the topics involved, because guessing between two answers is worse than saying you cannot.
The API reference has the full list with status codes.
What your application should do
Render nothing. Not an empty panel, not a question mark that opens a blank tooltip, not "Help unavailable". A component with no content should disappear. Absence of help is not an error, and the user cannot act on it.
Never block. A help request that is slow must not delay anything the user came to do. Give it a timeout and treat the timeout as missing.
Never show the key. billing.invoice.explained in the interface is an internal name leaking into your product. If you want a placeholder in development, make sure it cannot reach production.
Log it once, not per render. A missing key that logs on every mouse hover buries everything else in your logs. Count it per key.
Be loud in development, silent in production. The developer who added the component should see the gap immediately. The user should never know there was supposed to be something there.
Keep a register. The list worth having is which keys your product asks for and which of them resolve. That list tells a writer exactly what to write next, in the order the product asks for it, and it tells you which topics nothing asks for any more.
How other tools answer
i18n libraries. In i18next you pass a default value at the call site, or a list of fallback keys where the first one found wins, and saveMissing reports missing keys to your backend. So the fallback is something you write into the code, which is fine for labels and means the safety net lives in the release you are trying to edit around.
Firebase Remote Config. If no value was fetched from the backend, the app uses the in-app default value; if there is no in-app default, it falls back to a static type value such as 0 or false. There is always an answer, and for help text that answer is whatever shipped with your last release.
A headless CMS. A query that matches nothing returns an empty result set. There is no distinction between never written and not published unless you built one into your content model, and the behaviour in each component is yours to define.
The difference between these and a system built for help is not whether you can handle a missing key. It is whether the tool tells you enough to know whose problem it is.
The one decision worth making up front
Write down, once, what a help component does with nothing: what it renders, what it logs, how long it waits, and what happens in development. Then make that the only implementation, in one place, used by every component that fetches text.
The alternative is what most products have, which is thirty components with thirty opinions, of which four render an empty box and one shows the key.
How to manage in-app help covers where the text should live, and how to integrate it is the request itself.
Sources
All read on 22 September 2026.
- i18next: essentials: default values, fallback keys and
saveMissing - Firebase Remote Config parameters: in-app default values, and static type values when no default exists
- Our own codes are from the live delivery API at
https://www.helpccms.com/api/deploy, checked on the same day