Skip to main content

Troubleshooting

Reviewed against the package README and published 1.0.0 release (September 27, 2026).

Availability says available but every generation fails​

Symptom. availability() reports { available: true }, capabilities() reports contextWindow: UNKNOWN (the framework returned 0), and every generate/stream fails with an unknown error whose cause mentions SensitiveContentAnalysisML error 15 or ModelManagerError 1013. Token counting throws too.

What it is. The on-device model stack is wedged. This is observed behavior on a development Mac, not a hypothetical: availability is a check on configuration, not a health check, which is why the documentation repeats that available: true means "nothing known is blocking", never "the next request will succeed".

Remedies, in order of increasing disruption. Wait — it often clears itself within minutes. Toggle Apple Intelligence off and back on in Settings. Reboot the device or Mac. On a Mac, confirm that the model assets are actually present rather than mid-download.

Why the package behaves the way it does. Untyped NSErrors from the native layer map to unknown with transient: true rather than crashing the request path, and unknownTransient is a fallback trigger that is on by default — so a router with a cloud provider configured routes around a wedged stack instead of failing the user's turn. This is the entire reason that lane exists in the taxonomy. If you are running a single Apple provider with no fallback, you will see the raw error; that is the honest outcome.

The native module is missing at runtime though the build was green​

Symptom. The app builds with no errors and no warnings, and then createAppleProvider() reports unsupportedPlatform on a device that should support the model, or requireNativeModule('OnDeviceLlm') fails outright.

Cause. expo-modules-autolinking filters modules by deployment target. The podspec now declares iOS 16.4 — ExpoModulesCore's own floor and the Expo template's default — so this only bites an app whose own deployment target is set below 16.4. If your app's Podfile platform is lower than that, pod install silently omits the module entirely: Podfile.lock has no entry for it, and the build succeeds because nothing referenced it. This is unrelated to the on-device model's own iOS 26 floor — a device below 26 still links the module and gets unsupportedPlatform from it at runtime, which is the working, intended fallback path (see What differs on iOS 26).

Fix. Raise your app's deployment target to at least 16.4 (via expo-build-properties in app.json, or your Podfile directly), then reinstall pods. Raise the app target's own IPHONEOS_DEPLOYMENT_TARGET too, or the app's Swift fails to compile with a "module 'OnDeviceLlm' has a minimum deployment target of iOS 16.4" error. Check Podfile.lock for an OnDeviceLlm entry as the confirmation step — a green build is not one.

Metro cannot resolve the subpath exports​

Metro has resolved package.json exports by default since React Native 0.79, so on the supported floor (RN 0.86 / Expo SDK 57) the five entry points resolve with no configuration. If you have opted out with unstable_enablePackageExports: false, turn it back on; there is no proxy-directory fallback and none is planned.

If you are working against a local checkout the way example/ does — Metro extraNodeModules pointing at the repo, watchFolders including it — watch for the nested-resolution trap: babel.config.js's require('babel-preset-expo') walks up out of the app's own node_modules and can find an older copy at the repo root, paired with an older React Native. The symptom is an unrelated-looking transform failure such as "Unable to determine event arguments for onModeChange", and expo export fails outright. The fix is to add babel-preset-expo to the app's own devDependencies, pinned to the version its expo depends on, so local resolution wins.

The app crashes at launch with UIScene life cycle is required​

A freshly generated Expo 57 app targeting iOS 27 may require the scene lifecycle migration documented by the package. Version 1.0.0 includes an Expo config plugin for it:

app.json (excerpt)
{
"expo": {
"plugins": ["@taaltreelabs/on-device-llm"]
}
}

Keep your existing plugins, and follow the configuration in Getting started. Run npx expo prebuild --platform ios, then npx expo run:ios --device. A JavaScript reload cannot apply this native change.

The plugin patches only a recognized Expo AppDelegate template. If yours is customized, it warns and leaves that file alone. Follow the package's manual scene lifecycle migration, preserving your custom native behavior.