mapbox-navigation-ios icon indicating copy to clipboard operation
mapbox-navigation-ios copied to clipboard

[Bug]: Crash when rerouting during active guidance with routes calculated with map matching options

Open eFagerman opened this issue 4 months ago • 9 comments

Mapbox Navigation SDK version

3.10, 3.11 (> 3.9.2)

Steps to reproduce

  1. Start an active guidance with routes calculated with map matching options
  2. Go off route.

Expected behavior

A new route is created and the active guidance continues.

Actual behavior

Crash: [Error, nav-native]: RouteParserWorker::parseDirectionsResponse error: steps is an empty array. libc++abi: terminating due to uncaught exception of type std::runtime_error: steps is an empty array.

Is this a one-time issue or a repeatable issue?

repeatable

eFagerman avatar Sep 03 '25 20:09 eFagerman

var coreConfig = CoreConfig(predictiveCacheConfig: .init()) coreConfig.routingConfig.fasterRouteDetectionConfig = nil coreConfig.routingConfig.prefersOnlineRoute = true coreConfig.routingConfig.rerouteConfig.detectsReroute = true coreConfig.routingConfig.rerouteConfig.rerouteStrategyForMatchRoute = .navigateToFinalDestination

eFagerman avatar Sep 03 '25 20:09 eFagerman

Hello, thank you for reporting! We’re looking into it and will update you here.

volkdmitri avatar Sep 05 '25 17:09 volkdmitri

Hi @eFagerman! I was not immediately able to reproduce the crash. If you are able to reliably repeat it, could you provide some more detail on the scenario? For example, the URLs of route requests that happen before the crash: the original Map Matching API request and probably the rerouting Directions API request. (Please mind your access token.)

Normally, I might ask you to record a history file (example), but that may not be possible here if the crash happens 100% of the time in your scenario.

roopepal avatar Sep 09 '25 12:09 roopepal

Hi, thanks for looking into this issue. I hope this log (logLevel = .debug) helps you.

[Warning, nav-native]: Reroute from map-matching api is switched to directions api route having the destination as one waypoint, see NavigatorConfig::rerouteStrategyForMatchRoute [Info, nav-native]: Reroute is started. [Debug, navigation-ios/navigation]: Reroute was detected. [Info, nav-native]: Reroute requested with URL 'https://api.mapbox.com/directions/v5/mapbox/driving/-122.065251437%2C37.3341861054%3B-122.097676%2C37.359936?access_token=****02-w&annotations=distance%2Cduration&bearings=286.887%2C45%3B&context=reroute&continue_straight=true&geometries=polyline6&language=en&overview=full&radiuses=5%3B&reason=deviation&waypoints=0%3B1' [Info, nav-native]: OnlineRouter::getRoute id 2174241 request: https://api.mapbox.com/directions/v5/mapbox/driving/-122.065251437%2C37.3341861054%3B-122.097676%2C37.359936?access_token=****02-w&annotations=distance%2Cduration&bearings=286.887%2C45%3B&context=reroute&continue_straight=true&geometries=polyline6&language=en&overview=full&radiuses=5%3B&reason=deviation&waypoints=0%3B1 [Debug, nav-native]: Retryable task: executing with retry. Attempt: 1. Retries: 2 [Debug, nav-native]: Directions Service: Get route request: https://api.mapbox.com/directions/v5/mapbox/driving/-122.065251437%2C37.3341861054%3B-122.097676%2C37.359936?access_token=****02-w&annotations=distance%2Cduration&bearings=286.887%2C45%3B&context=reroute&continue_straight=true&geometries=polyline6&language=en&overview=full&radiuses=5%3B&reason=deviation&waypoints=0%3B1 [Info, nav-native]: OnboardRouter(main): getRoute id 3340767 request: https://api.mapbox.com/directions/v5/mapbox/driving/-122.065251437%2C37.3341861054%3B-122.097676%2C37.359936?access_token=****02-w&annotations=distance%2Cduration&bearings=286.887%2C45%3B&context=reroute&continue_straight=true&geometries=polyline6&language=en&overview=full&radiuses=5%3B&reason=deviation&waypoints=0%3B1 [Info, nav-native]: getRoute id 3340767: URI parsed successfully [Info, valhalla]: Using simple cache [Warning, valhalla]: No metadata found for tiles, using 'transition_scale_factors_version=0' [Info, valhalla]: Could not load goga-toll-cost file: [Info, valhalla]: Start loading and parsing Z-GOGA data [Info, valhalla]: Could not load z-goga file: [Info, valhalla]: vi_VN.UTF-8 locale is not available on this system. Using custom one instead. [Info, valhalla]: th_TH.UTF-8 locale is not available on this system. Using custom one instead. [Debug, nav-native]: Directions Service: FetchDirections successful response {"routes":[{"weight_name":"auto","weight":312.973,"duration":274.047,"distance":5773.206,"legs":[{"via_waypoints":[],"annotation":{"distance":[18.7,47.3,51,45.5,31,0.5,0.2,13.9,48.5,25.1,16.3,10.1,25.8,11.3,38.4,40.4,288.7,46,44.4,42.8,47,42.4,46.4,44,46.4,45.4,44.3,43.1,42.1,44.1,43.9,45.2,46.4,241.3,48.2,45.2,44.1,39.8,418.2,42.2,43.6,60.3,2.5,23.1,3.2,81.5,48.2,42.9,41.1,38.8,43.3,241.6,42.7,43.3,43.1,42.1,43,42.5,500.8,42.3,42.4,40.7,42.4,43.4,28.6,29.1,28,29.8,30.2,126.3,14.7,151.6,18.3,18.7,19.8,9.3,0.4,7.4,21.1,30.2,0.5,1.8,1.1,1.9,8.8,13.6,14,13,16,33.7,24.5,5.7,16.1,28.2,26.6,35.5,12.3,24.7,19,27.7,33.1,29.1,110.9,1.8,9.6,5.8,0.5,3.4,152.3,58.1,15,52.5,9.3,2.2,4.8,78.7,72.4,37.5,12.1,36.5,14.8,6.6,5.8,13.9,17.9,18.4,23.4,2.1,10.4,9.6,10.2,12,19.5,10.7,39.7],"duration":[0.668,1.685,1.818,1.62,1.106,0.019,0.006,0.496,1.729,0.894,0.581,0.337,0.859,0.375,1.282,1.344,9.626,1.532,1.483,1.426,1.567,1.411,1.549,1.465,1.549,1.512,1.477,1.438,1.401,1.472,1.461,1.508,1.547,8.045,1.605,1.508,1.469,1.327,13.94,1.408,1.453,2.009,0.084,0.769,0.108,2.717,1.606,1.432,1.369,1.292,1.446,8.05,1.425,1.442,1.439,1.401,1.435,1.417,16.693,1.409,1.415,1.355,1.415,1.444,0.954,0.97,0.934,0.991,1.008,4.208,1.141,11.616,1.397,1.437,1.51,0.718,0.029,0.567,1.614,2.311,0.04,0.137,0.083,0.15,0.675,4.38,1.26,1.165,1.441,2.361,1.66,0.401,1.053,1.842,1.709,2.194,0.782,1.509,1.212,1.725,2.054,1.804,10.514,0.178,0.901,0.42,0.034,0.242,10.75,3.62,0.954,3.271,0.612,0.15,0.31,5.065,4.842,2.653,0.921,2.928,1.532,0.686,0.592,1.431,3.839,3.879,4.963,0.45,2.214,1.335,1.413,1.196,4.13,1.036,3.777]},"admins":[{"iso_3166_1_alpha3":"USA","iso_3166_1":"US"}],"weight":312.973,"duration":274.047,"steps":[],"distance":5773.206,"summary":"I... [Info, nav-native]: OnlineRouter::getRoute id 2174241 successfully returns [Debug, nav-native]: ParallelHybridRouter::getRoute online returned successfuly,cancelling onboard router libc++abi: terminating due to uncaught exception of type std::runtime_error: steps is an empty array.

eFagerman avatar Sep 10 '25 21:09 eFagerman

Hi @eFagerman

Thank you for additional logs. The crash was caused by an incorrect route request parameters. See this:

libc++abi: terminating due to uncaught exception of type std::runtime_error: steps is an empty array.

The route request in the logs does not include the parameter steps=true. As a result, the returned route does not contain step-by-step navigation instructions. While the crash should not have happened (and we are working on a fix to prevent it), the root cause is the missing reroute request parameter.

Could you confirm whether you are using any custom route options or a modified reroute URL? By default, the steps=true parameter is automatically added to navigation requests. Could you please show your full code for CoreConfig creation and all following modification, as well as the NavigatonMatchOptions creation for the initial request.

You can still manually add this parameter and other recommended parameters to the reroute request by implementing this customization:

urlOptionsCustomization: EquatableClosure { urlString in
    guard var components = URLComponents(string: urlString) else {
        return urlString
    }

    // recommended parameters to update
    let paramsToEnable = ["steps", "voice_instructions", "banner_instructions"]
    let existing = components.queryItems?.filter {
        !paramsToEnable.contains($0.name)
    } ?? []
    components.queryItems = existing + paramsToEnable.map { URLQueryItem(name: $0, value: "true") }
    return components.url?.absoluteString ?? urlString
}

kried avatar Sep 15 '25 13:09 kried

Hi again,

I’m setting steps=true (options.includesSteps = true) — see code below. I think I’ve found a lead. I get a log error when calculating a route using map-matching options if one of the waypoints is created from a CLLocation with heading (not just a CLLocationCoordinate2D). If I create the waypoints using only CLLocationCoordinate2D, the log error doesn’t appear and the app stops crashing.

FYI: I see the log error Failed to parse URI parameter "radiuses"="5.0;unlimited" whether or not I include a radiuses query parameter. This seems tied only to how the Waypoint is constructed.

First waypoint created from location => log error, and the app crashes

let options = createNavigationMatchOptions(
coordinates: processedTrailCoordinates,
waypoints: [Waypoint(location: userLocation), Waypoint(coordinate: currentDestination)],
snapToRoadRadius: radius)

First waypoint created from a coordinate => no error log, and no crash.

let options = createNavigationMatchOptions(
coordinates: processedTrailCoordinates,
waypoints: [Waypoint(coordinate: userLocation.coordinate), Waypoint(coordinate: currentDestination)],
snapToRoadRadius: radius)

Log: [Debug, nav-native]: Retryable task: executing with retry. Attempt: 1. Retries: 1 [Debug, nav-native]: MapMatching Service: Get route request: https://api.mapbox.com/matching/v5/mapbox/driving/-122.04381,37.334461;-122.092971,37.356774?geometries=polyline6&overview=full&steps=true&language=en-SE&voice_instructions=true&voice_units=metric&banner_instructions=true&radiuses=5.0;unlimited&annotations=duration,maxspeed&tidy=true&access_token=****02-w [Info, nav-native]: OnlineRouter::getRouteMapMatched id 4511790 successfully returns [Error, nav-native]: RouteParserWorker::parseMapMatchingResponse error on request parse: Failed to parse URI parameter "radiuses"="5.0;unlimited"

Function that creates the NavigationMatchOptions

  private func createNavigationMatchOptions(
        coordinates: [CLLocationCoordinate2D],
        waypoints: [Waypoint],
        snapToRoadRadius: Double?
    ) -> NavigationMatchOptions {

        var queryItems: [URLQueryItem]? = nil
        if let snapToRoadRadius {
            // Setting up a radius for each GPX track coordinate
            let radiusesString = Array(repeating: String(snapToRoadRadius), count: coordinates.count).joined(separator: ";")
            let radiusesQueryItem = URLQueryItem(name: "radiuses", value: radiusesString)
            queryItems = [radiusesQueryItem]
        }
        
        let options = NavigationMatchOptions(
            coordinates: coordinates,
            profileIdentifier: .automobile,
            queryItems: queryItems
        )
        options.routeShapeResolution = .full
        options.resamplesTraces = true
        options.includesSteps = true
        options.includesVisualInstructions = true
        options.distanceMeasurementSystem = distanceMeasurementSystem
        if !waypoints.isEmpty {
            options.waypoints = waypoints
        }
        
        return options
    }

eFagerman avatar Sep 16 '25 19:09 eFagerman

@eFagerman

Yes, the reason for the problem is the parameter radiuses. When rerouting from MapMatching API to the Directions API, the number of waypoints changes. So the previous value for the radiuses is not valid anymore.

Of course, the crash is not expected in this case, and we will work on the issue to fix the crash. At the same time, you can temporarily workaround the problem by not setting this parameter.

kried avatar Sep 19 '25 13:09 kried

Great! I just want to point out once more, that the app crashes, and l get the error log: "radiuses"="5.0;unlimited", whether or not I'am setting the radiuses parameter in the NavigationMatchOptions. The crash and the error log only happens during a rerouting if a set a Waypoint with CLLocation Waypoint(location: userLocation).

eFagerman avatar Sep 19 '25 18:09 eFagerman

Hi @eFagerman

I'm writing to inform you that Nav SDK v3.16.1 fixed the crash.

kried avatar Nov 25 '25 16:11 kried