Troubleshooting & Diagnostics Guide
Common Issues, Expo SDK 57 Nuances, Permissions, and Hardware Diagnostics
This guide outlines common errors, hardware lifecycle caveats, and resolution steps for PixelKit developers.
Issue Index
Section titled “Issue Index”- KeepAwake Tag Error in Expo SDK 57
- StatusBar BackgroundColor Deprecation
- Camera Permission & Simulator Fallback
- ADPF Thermal Throttling Mitigation
- Hermes Bytecode Metro Bundling Verification
- Keystore and SecureStore access modes
- A hook returns null and its source says unavailable
1. KeepAwake Tag Error in Expo SDK 57
Section titled “1. KeepAwake Tag Error in Expo SDK 57”Symptom
Section titled “Symptom”Unhandled promise rejection: activateKeepAwake requires a tag parameter in Expo SDK 57.
In Expo SDK 57 (~57.0.20), activateKeepAwakeAsync() requires passing a string tag to identify the wake-lock owner.
Resolution
Section titled “Resolution”Always pass a unique tag when activating or deactivating:
import { activateKeepAwakeAsync, deactivateKeepAwake } from 'expo-keep-awake';
const TAG = 'pixelkit_display_lock';
// CORRECTawait activateKeepAwakeAsync(TAG);deactivateKeepAwake(TAG);
// WRONG (Omitted tag throws in Expo 57)await activateKeepAwakeAsync();2. StatusBar BackgroundColor Deprecation
Section titled “2. StatusBar BackgroundColor Deprecation”Symptom
Section titled “Symptom”TypeScript warning or runtime error: Property 'backgroundColor' does not exist on type 'IntrinsicAttributes & StatusBarProps'.
In Expo SDK 57, <StatusBar /> from expo-status-bar dropped the backgroundColor prop in favor of root View background styling.
Resolution
Section titled “Resolution”Style the parent <SafeAreaView> or root <View> with Colors.dark.background (#0E1119) and use <StatusBar style="light" />:
<SafeAreaView style={{ flex: 1, backgroundColor: '#0E1119' }}> <StatusBar style="light" /> {/* Content */}</SafeAreaView>3. Camera Permission & Simulator Fallback
Section titled “3. Camera Permission & Simulator Fallback”Symptom
Section titled “Symptom”Camera screen throws Camera permission not granted on Android emulator or initial launch.
Resolution
Section titled “Resolution”useCamera() includes an asynchronous permission check with a graceful fallback. Ensure app.json includes the camera permission:
"android": { "permissions": [ "android.permission.CAMERA", "android.permission.RECORD_AUDIO" ]}If running in an emulator without camera hardware, useVisionAI() provides gallery photo picking via captureAndAnalyze(false).
4. ADPF Thermal Throttling Mitigation
Section titled “4. ADPF Thermal Throttling Mitigation”Symptom
Section titled “Symptom”Frame drops or stutter when rendering complex graphics or processing sustained neural workloads.
Resolution
Section titled “Resolution”Check useADPF().thermalStatus:
const { thermalStatus } = useADPF();
if (thermalStatus === 'severe' || thermalStatus === 'critical') { // 1. Back off sensor polling to 500ms // 2. Pause non-essential background tensor passes // 3. Extinguish flashlight / HiLight ring}5. Hermes Bytecode Metro Bundling Verification
Section titled “5. Hermes Bytecode Metro Bundling Verification”To ensure all TypeScript modules compile and package cleanly without syntax or bundling errors:
# 1. Typechecknpm run typecheck
# 2. Bundle Hermes bytecode for Androidnpx expo export -p androidIf bundling reports an error, clean the Metro cache:
npx expo start -c6. Keystore and SecureStore access modes
Section titled “6. Keystore and SecureStore access modes”On Android, expo-secure-store encrypts values with a key held in the Android Keystore, StrongBox-backed on this device.
useSecurity().saveSecureItem(key, value)usesWHEN_UNLOCKED_THIS_DEVICE_ONLY, so a value is readable only while the device is unlocked and never leaves this phone.- On web there is no Keystore: the hook falls back to
localStorage, which is not encrypted.isHardwareBackedisfalsethere, so gate anything sensitive on it. isPostQuantumProtectedis alwaysfalse. Android 17 defines post-quantum key types; SecureStore does not use them.
7. A hook returns null and its source says unavailable
Section titled “7. A hook returns null and its source says unavailable”Symptom
Section titled “Symptom”A metric renders as “—” and source is 'unavailable'.
This is the SDK working as designed, not a bug. There is no simulated provenance value: when a reading cannot be taken, the value is null rather than a plausible substitute. Common reasons:
| Cause | Check | Fix |
|---|---|---|
| Running in Expo Go or on web | PixelNative and PixelNano resolve to null there |
Use a development build on the device |
| Permission not granted | hasPermission, permissionGranted, hasHardware on the hook |
Request it, then re-read |
| The device lacks the hardware | useCapabilities() — hasUWB, hasHiLight, hasStrongBox, hasNFC |
Hide the control rather than showing one that fails |
| The daemon is not running (HiLight only) | availability === 'unavailable' |
npm run hilight:daemon |
| First sample has not arrived | hasMotionSample, hasFix, hasRead, isReady |
Wait; render “—” meanwhile |
Resolution
Section titled “Resolution”Render null as “—”, pass source to MetricCard so the tag is visible, and read the hook’s error field for the reason. Never substitute a default.