Health
Installs that asked for a flow and got nothing back, grouped by what went wrong.
What it counts
Open Health in the sidebar and you get Flow health: every install that asked for a flow and was shown nothing. Nothing published, no network, a build too old to read the artifact.
It is deliberately not a funnel. An install counted here never reached a screen, so this is a delivery problem rather than a drop-off, and folding the two together would blame a flow's content for something its content had no part in.
Installs are counted, never listed. The page says how many devices, not which.
How to read a row
One row per flow and reason — not one per event. A single missing release produces one failure per install per launch, so the raw stream is thousands of identical rows describing one mistake. Each row carries two numbers: how many distinct installs hit it, and how many times it happened across all of them.
Rows are ordered by installs, not by failures. One phone failing fifty times is not an outage; fifty phones failing once is.
A row also shows the channel it happened on — Staging or Production — when it was last seen, the key the device asked for (a placement key, even though the SDK parameter is named flowKey), and the flow versions involved. Version none means the device never got an artifact at all, which is what a missing release looks like. If more pairs exist than the list shows, a line under it reports the total for the window. Failures outlive the flow that caused them: a deleted flow still shows, named (deleted flow).
The window buttons offer the last 1, 7, or 30 days. It opens on 7.
The reasons
| Label | What happened, and what to do |
|---|---|
| Nothing published | No version is live on that channel. Set one live, or expect these installs to see nothing. |
| App too old | A version is live, but this build of your app is too old to render it. These installs need an app update — publishing again will not reach them. |
| Key rejected | The SDK key was refused. Usually revoked, or built against the other channel. |
| No network | The device had no connection and no cached copy to fall back on. Expect a background rate here; a jump is the signal, not the presence. |
| Could not be read | The artifact reached the device but its schema was beyond what this build understands. |
| Request failed | The fetch itself failed — a timeout, a DNS failure, a proxy in the way. |
| Failed while rendering | The flow downloaded and then threw mid-render. This one is a bug worth reporting. |
| Already showing a flow | A second present() arrived while one flow was still up. The SDK shows one at a time. |
| Unknown | The device reported no reason at all. |
One failure never appears here. Calling present() before configure() is always an integration bug and always yours to fix, but configure() is what builds the reporting pipeline — before it runs there is nothing to spool an event into. The SDK hands that failure straight back to your call site as a failed result. Watch the value present() returns, not this page.
What an empty list does and does not mean
The set of reasons is closed and the server validates against it, so keep your SDK and this console in step: a reason the server does not recognise is rejected rather than stored. A reason the server accepts but the console has no label for yet is shown as its raw identifier. You will meet one of those — a lane you deliberately pointed at nothing reports no_content, which is the configured answer rather than a fault.
Related
Flows covers publishing a version and what each badge on the flows list means. Placements decides which flow a key gets back. SDK covers keys, channels, and the calls that produce these reports.