googlesamples / googlesamples/mlkit
[GenAI] checkStatus()/checkFeatureStatus() throws 606 FEATURE_NOT_FOUND instead of returning UNAVAILABLE when AICore is present but the feature is not provisioned
- Dominant language
- Kotlin
- Stars
- 4.3k
- Forks
- 3.1k
- PR merge metrics
- No merged PRs in 30d
Description
### Summary
The documentation prescribes `checkFeatureStatus()` / `checkStatus()` as *the* way to find out whether a feature is usable, and `UNAVAILABLE` is documented to cover exactly the "not supported on this device" case. In practice, **these APIs throw `GenAiException(606) FEATURE_NOT_FOUND` instead of returning `UNAVAILABLE`** whenever AICore is installed but the requested feature is not provisioned for the device.
This makes the documented mitigation impossible to apply: the mitigation itself throws.
> "all these setup failure cases can be caught by the `checkFeatureStatus()` or `checkStatus()` APIs. Make sure to call `checkFeatureStatus()` or `checkStatus()` first before showing any related UI, so your app users won't see these errors in any cases."
> — [Get started with Prompt API](https://developers.google.com/ml-kit/genai/prompt/android/get-started)
`UNAVAILABLE` is documented as *"Gemini Nano not supported on this device **or device hasn't fetched the latest configuration to support it**"*, which describes this situation precisely.
### Impact
An app written the way the official sample suggests crashes:
```kotlin
when (model.checkStatus()) {
FeatureStatus.UNAVAILABLE -> showFallback()
FeatureStatus.DOWNLOADABLE -> download()
FeatureStatus.AVAILABLE -> run()
}
```
It never reaches the `UNAVAILABLE` branch on any device where the feature is not provisioned — which is the majority of Android devices.
### Reproductions (2 devices, 2 APIs, 2 library versions)
| # | Device | OS | Library | API | Result |
|---|---|---|---|---|---|
| 1 | **Pixel 9a** (`tegu`) | **Android 17** (`CP2A.260705.006`) | `genai-summarization` | `checkFeatureStatus()` | **throws 606**, Feature **633** not available |
| 2 | **Pixel 9a** | Android 17 | `genai-prompt:1.0.0-beta2` | `checkStatus()` | **throws 606** for all 5 `ModelConfig` (features 636 / 645 / 646 / 647) |
| 3 | **Pixel 10** (`frankel`) | Android 16 (`CP1A.260505.005`) | `genai-prompt:1.0.0-beta3` | `checkStatus()` | **throws 606**, Feature 648 not available |
Reproduction 1 is the clearest case: `genai-summarization` has not been updated since 2025-05-14, and Android 17 is the current release. This is not a beta-channel or a stale-library problem.
### Control — the API *can* return UNAVAILABLE, and does so when AICore is absent
On a **Pixel 7a**, `com.google.android.aicore` is only a ROM stub that Play has never replaced:
```
versionName = 0.stub.aicore_20250130.00_RC01.721552006
codePath = /product/priv-app/AICorePrebuilt-aicore_20250130.00_RC01
lastUpdateTime = 2009-01-01 (never updated by Play)
```
On that device, both APIs behave **correctly**:
| Device | AICore | `checkFeatureStatus()` / `checkStatus()` |
|---|---|---|
| **Pixel 7a** | **stub** (nothing to bind to) | **returns `UNAVAILABLE` (0)** — correct |
| **Pixel 9a** | real, Play-updated 2026-06-20, binds, loads EdgeTPU libs, **feature not provisioned** | **throws 606** |
| **Pixel 10** + beta3 | real, **feature 648 not provisioned** | **throws 606** |
So the failure is specific to **"AICore is present but the requested feature is not provisioned"** — which is precisely the second half of the documented `UNAVAILABLE` definition ("or device hasn't fetched the latest configuration to support it").
On the Pixel 9a, AICore is demonstrably alive — it starts and binds when ML Kit is called:
```
ActivityManager: Start proc 21133:com.google.android.aicore/u0a129
for bound-service {com.google.android.aicore/...AiCoreMultiUserService}
nativeloader: ... uses_libraries=libedgetpu_util.so:libedgetpu_client.google.so:...
```
### Expected
`checkFeatureStatus()` / `checkStatus()` return `UNAVAILABLE` when the requested feature is not provisioned, and throw only for genuinely unexpected conditions. The Pixel 7a behaviour is the correct one; it should also apply when AICore is installed.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reproducing the documented Kotlin flows using checkFeatureStatus() and checkStatus() for an installed AICore device where the requested feature is not provisioned, comparing them with the Pixel 7a stub behavior. Review the Get started with Prompt API guidance and the genai-summarization and genai-prompt examples; done means the APIs return UNAVAILABLE rather than GenAiException(606) for this condition.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, kotlin
- Domain
- ai, mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100