Required Reading
Plugin Version
5.1.1
Mobile operating-system(s)
Device Manufacturer(s) and Model(s)
Apple iPhone 16 Pro Max (iPhone16,2)
Device operating-systems(s)
iOS 26.5 (23F77) — Beta
React Native / Expo version
React Native 0.81.5, Expo 54.0.33
What do you require assistance about?
Issue 1 — Watchdog Kill (0x8BADF00D) During Background Location Processing
Crash Details
- Incident ID: DD1ED214-20D4-4CF9-A263-8344FAC4B274
- Crash timestamp: 2026-05-31 13:01:25 +0530
- Exception type: EXC_CRASH (SIGKILL)
- Termination reason: FRONTBOARD – domain:10 code:0x8BADF00D
- Watchdog event: scene-update (Background)
- Process role: Non UI (background)
- Process uptime at crash: ~850 seconds
- Lock state duration: 122 seconds (device was locked)
- Elapsed CPU at kill: 14.030s total (user 7.970s, system 6.060s), 44% CPU — application CPU was only 0.004s (0%), meaning watchdog fired on wall-clock time, not CPU burn. This is a locking/deadlock issue, not a performance issue.
Faulting Thread 0 — com.apple.main-thread (deadlocked)
Main thread stuck in _dispatch_once_wait, blocked on a lock triggered by a CoreLocation → LocationSupport callback:
0 __ulock_wait libsystem_kernel.dylib
1 _dlock_wait libdispatch.dylib
2 _dispatch_once_wait.cold.1 libdispatch.dylib
3 _dispatch_once_wait libdispatch.dylib
4 [imageOffset: 13028112] HarborSuite
5 [imageOffset: 12759580] HarborSuite
6 [imageOffset: 12785560] HarborSuite
7 [imageOffset: 240992] LocationSupport.framework
8 [imageOffset: 16936] LocationSupport.framework
9 [imageOffset: 5572] CoreLocation.framework
10 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ CoreFoundation
11 __CFRunLoopDoBlocks CoreFoundation
12 __CFRunLoopRun CoreFoundation
13 _CFRunLoopRunSpecificWithOptions CoreFoundation
14 GSEventRunModal GraphicsServices
15 -[UIApplication _run] UIKitCore
16 UIApplicationMain UIKitCore
Thread 3 — com.meta.react.turbomodulemanager.queue (blocked)
Simultaneously blocked in _dispatch_sync_f_slow trying to invoke TSLocationManager via ObjCTurboModule::performMethodInvocation, creating a circular deadlock with Thread 0:
0 __ulock_wait
1 _dispatch_thread_main_event_wait_slow
2 __DISPATCH_WAIT_FOR_QUEUE__
3 _dispatch_sync_f_slow
4–9 [HarborSuite: 13205856, 13029092, 13028192, 111076, 17840, 13028112]
10 [HarborSuite: 12777140 → 12923764 → 10298968]
11 __invoking___
12 -[NSInvocation invoke]
13 -[NSInvocation invokeWithTarget:]
14 invocation function for block in ObjCTurboModule::performMethodInvocation
15 ObjCTurboModule::performMethodInvocation::$_1::operator()
16 _dispatch_call_block_and_release
_dispatch_client_callout
_dispatch_lane_serial_drain
_dispatch_lane_invoke
_dispatch_root_queue_drain_deferred_wlh
_dispatch_workloop_worker_thread
_pthread_wqthread
start_wqthread
Root Cause Analysis
TSLocationManager delivers a location event to the main thread (CoreLocation → LocationSupport callback), which hits a dispatch_once guarded section inside HarborSuite. Simultaneously, the TurboModule manager queue attempts a synchronous dispatch onto the main thread to invoke TSLocationManager via ObjCTurboModule::performMethodInvocation. Both threads are waiting for a lock the other holds → deadlock → iOS watchdog kills the process.
This appears specific to or exacerbated by New Architecture (TurboModules) and possibly iOS 26 beta where LocationSupport.framework behaviour may have changed.
Full .ips crash log attached.
Issue 2 — Cold Start Location Gap Exceeds Documented ~200 m
Description
After a cold start (process killed and relaunched by iOS), the first recorded location is significantly farther than the documented ~200 m from the last known position, causing a large visible gap in the track.
Screenshot attached showing the gap on the map.
Steps to Reproduce
- Start background tracking.
- Move continuously so locations are being recorded.
- Force-kill the app from the app switcher (or let iOS kill it).
- Relaunch the app (cold start).
- Compare the last pre-kill location with the first post-relaunch location.
Expected Behaviour
Cold-start gap of at most ~200 m as documented.
Actual Behaviour
Gap is substantially larger — observed several hundred meters to over 1 km in some cases.
Additional Context
- Device: iPhone 16 Pro Max (A18 Pro chip), iOS 26 beta.
- Using New Architecture (TurboModules) — module initialization delay on cold start may be pushing the first location callback further out.
expo-location (19.0.8) and expo-task-manager (14.0.9) are present alongside react-native-background-geolocation. Possible conflict in location session ownership on cold start.
- TSLocationManager native pod: 4.1.7
- Distribution: TestFlight (beta), App version: 2.0.8 (build 17)
<img width="392" height="344" alt="Image" src="https://github.com/user-attachments/assets/0f1ef800-e6e4-4dfd-b829-41cd3681dd18" />
<img width="1472" height="1092" alt="Image" src="https://github.com/user-attachments/assets/36d938e5-a43d-4309-b982-6da0c19e04ed" />
### [Optional] Plugin Code and/or Config
```typescript
const buildConfig = (token) => ({
// ── Accuracy ────────────────────────────────────────────────────────────
desiredAccuracy: BackgroundGeolocation.DesiredAccuracy.High,
distanceFilter: 10,
disableElasticity: true, // consistent tracking at all speeds
elasticityMultiplier: 1,
motionTriggerDelay: 0, // record immediately on motion
disableLocationAuthorizationAlert: Platform.OS == "ios", // ONLY Android device get device default turn on location popup
// ── Persistence: survive app kill + reboot ──────────────────────────────
stopOnTerminate: false,
startOnBoot: true,
enableHeadless: true,
locationAuthorizationRequest: "Always",
// ── Activity recognition ────────────────────────────────────────────────
stopTimeout: 5,
// ── Offline SQLite buffer ───────────────────────────────────────────────
maxRecordsToPersist: -1, // unlimited — never discard data
maxDaysToPersist: 2, // keep 2 days of buffered data
// ── Sync: one POST per location ─────────────────────────────────────────
autoSync: !!token,
autoSyncThreshold: 20,
batchSync: true,
maxBatchSize: 20,
// ── HTTP ────────────────────────────────────────────────────────────────
url: `${BASE_URL}/user-location-tracking/ingest`,
method: "POST",
httpRootProperty: ".",
headers: token ? { Authorization: `Bearer ${token}` } : {},
// Initial extras — kept in sync with RN AppState by wireAppStateToExtras().
extras: { app_state: APP_STATE.FOREGROUND },
// ── Android: foreground service + battery survival ──────────────────────
foregroundService: true,
notification: {
title: "Harbor Suite - Work Location",
text: "Location tracking is active for your work activities.",
channelName: "Location Tracking",
sticky: true,
},
locationUpdateInterval: 5000,
fastestLocationUpdateInterval: 2000,
deferTime: 0,
// ── Heartbeat ───────────────────────────────────────────────────────────
heartbeatInterval: 60,
// ── iOS ─────────────────────────────────────────────────────────────────
preventSuspend: true,
activityType: BackgroundGeolocation.ActivityType.OtherNavigation,
pausesLocationUpdatesAutomatically: false,
showsBackgroundLocationIndicator: true,
useSignificantChangesOnly: false,
locationTimeout: 30,
// ── Logging ─────────────────────────────────────────────────────────────
debug: false,
logLevel: BackgroundGeolocation.LogLevel.Verbose,
});
[Optional] Relevant log output
Required Reading
Plugin Version
5.1.1
Mobile operating-system(s)
Device Manufacturer(s) and Model(s)
Apple iPhone 16 Pro Max (iPhone16,2)
Device operating-systems(s)
iOS 26.5 (23F77) — Beta
React Native / Expo version
React Native 0.81.5, Expo 54.0.33
What do you require assistance about?
Issue 1 — Watchdog Kill (0x8BADF00D) During Background Location Processing
Crash Details
Faulting Thread 0 —
com.apple.main-thread(deadlocked)Main thread stuck in
_dispatch_once_wait, blocked on a lock triggered by a CoreLocation → LocationSupport callback:Thread 3 —
com.meta.react.turbomodulemanager.queue(blocked)Simultaneously blocked in
_dispatch_sync_f_slowtrying to invoke TSLocationManager viaObjCTurboModule::performMethodInvocation, creating a circular deadlock with Thread 0:Root Cause Analysis
TSLocationManagerdelivers a location event to the main thread (CoreLocation → LocationSupport callback), which hits adispatch_onceguarded section inside HarborSuite. Simultaneously, the TurboModule manager queue attempts a synchronous dispatch onto the main thread to invokeTSLocationManagerviaObjCTurboModule::performMethodInvocation. Both threads are waiting for a lock the other holds → deadlock → iOS watchdog kills the process.This appears specific to or exacerbated by New Architecture (TurboModules) and possibly iOS 26 beta where
LocationSupport.frameworkbehaviour may have changed.Full
.ipscrash log attached.Issue 2 — Cold Start Location Gap Exceeds Documented ~200 m
Description
After a cold start (process killed and relaunched by iOS), the first recorded location is significantly farther than the documented ~200 m from the last known position, causing a large visible gap in the track.
Screenshot attached showing the gap on the map.
Steps to Reproduce
Expected Behaviour
Cold-start gap of at most ~200 m as documented.
Actual Behaviour
Gap is substantially larger — observed several hundred meters to over 1 km in some cases.
Additional Context
expo-location(19.0.8) andexpo-task-manager(14.0.9) are present alongsidereact-native-background-geolocation. Possible conflict in location session ownership on cold start.[Optional] Relevant log output