NavigationPath state restoration crash (FB10718297)

Restoring a NavigationStack path (NavigationPath) from a codable representation, crashes the app with the following error:

Failed to decode item in navigation path at index 0. Perhaps the navigationDestination declarations have changed since the path was encoded?

Fatal error: throw through?

Note that the error is thrown when the view appears, not when the NavigationPath(representation) is initialized.

In this example, navigation declarations have not changed and restoration should succeed. However, even there was an error restoring the path, this should not be a fatal error. It should be handled gracefully. Consider a new app version being distributed where the destinations did changed. The stack restoration should fail and navigate to the root, but not crash.

Problem occurs both in iOS 16 beta 3 and macOS 13 beta 3.

struct Movie: Identifiable, Hashable, Codable {
    let id: Int
    let name: String
    let year: Int
}

struct TVShow: Identifiable, Hashable, Codable {
    let id: Int
    let name: String
    let episodes: Int
}

class Model: ObservableObject {
    let movies = [
        Movie(id: 1, name: "Blade Runner", year: 1982),
        Movie(id: 2, name: "Back to the Future", year: 1985),
        Movie(id: 3, name: "Mission Impossible", year: 1996),
    ]
    
    let shows = [
        TVShow(id: 1, name: "Cheers", episodes: 275),
        TVShow(id: 2, name: "Taxi", episodes: 114)
    ]
    
    @Published var path: NavigationPath
    
    init() {
        if let data = UserDefaults.standard.object(forKey: "path") as? Data {
            do {
                let representation = try JSONDecoder().decode(NavigationPath.CodableRepresentation.self, from: data)
                self.path = NavigationPath(representation)
            } catch {
                print("Unable to decode path \(error)")
                self.path = NavigationPath()
            }
        } else {
            self.path = NavigationPath()
        }
    }
    
    func save() {
        guard let representation = path.codable else { return }
        
        do {
            let encoder = JSONEncoder()
            let data = try encoder.encode(representation)
            
            UserDefaults.standard.set(data, forKey: "path")
        } catch {
            print("Unable to encode path \(error)")
        }
    }
}

struct ContentView: View {
    @Environment(\.scenePhase) private var scenePhase
    @StateObject var model = Model()
    
    var body: some View {
        NavigationStack(path: $model.path)
        {
            List {
                Section("Movies") {
                    ForEach(model.movies) { movie in
                        NavigationLink(movie.name, value: movie)
                    }
                }

                Section("TV Shows") {
                    ForEach(model.shows) { show in
                        NavigationLink(show.name, value: show)
                    }
                }
            }
            .navigationDestination(for: Movie.self, destination: { MovieView(movie: $0) })
            .navigationDestination(for: TVShow.self, destination: { TVShowView(show: $0) })
        }
        .onChange(of: scenePhase) { phase in
            if phase == .background {
                model.save()
            }
        }
        
    }
    
}

struct MovieView: View {
    let movie: Movie
    
    var body: some View {
        Form {
            LabeledContent("Title", value: movie.name)
            LabeledContent("Year" , value: "\(movie.year)")
        }
    }
}

struct TVShowView: View {
    let show: TVShow
    
    var body: some View {
        Form {
            LabeledContent("Title", value: show.name)
            LabeledContent("Episodes" , value: "\(show.episodes)")
        }
    }
}

This seems to be fixed now in Beta 5. Had the same issues yesterday and found this thread, but today with Beta 5 doesn't crash anymore.

Now this project crashes after restoring state and going back to the root level.

I'm getting this error: SwiftUI/NavigationPath.swift:214: Fatal error: attempting to remove 1 items from path with 1 items

NavigationPath state restoration crash (FB10718297)
 
 
Q