)]}'
{
  "commit": "086d4c5f25bfbb1a82e90d8cfdcebc2a298f09fa",
  "tree": "20441d0620c82f5b21f17c803351b279eba6c22a",
  "parents": [
    "c6277b366df72606716bb2a09abcd5f70cdc0664"
  ],
  "author": {
    "name": "Sam Rawlins",
    "email": "srawlins@google.com",
    "time": "Mon Nov 02 10:27:12 2026 -0800"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Mon Nov 02 10:27:12 2026 -0800"
  },
  "message": "Fix performance when JSON is invalid (#10005)\n\n* Fixes https://github.com/flutter/devtools/issues/4172\n\n1. **Fixed performance_model.dart:68-71**:\n  * Updated isEmpty to verify that there is no trace binary, no frames, and no rebuild model.\n\n2. **Guarded Perfetto trace loading in timeline_events_controller.dart:501-506**:\n  * Avoided attempting to process track events or load a trace into Perfetto when perfettoTraceBinary is null or empty, allowing offline Flutter frames to display cleanly.\n3. **Added validation in import_export.dart:72-106**:\n  * Added null-safety check for activeScreenId with user-facing notification if missing from the snapshot.\n  * Added a check verifying that the JSON contains data for activeScreenId (json.containsKey(activeScreenId) \u0026\u0026 json[activeScreenId] !\u003d null), preventing navigation to a broken snapshot screen and immediately notifying the user.\n4. **Added error handling and notifications in offline_data.dart:173-200**:\n  * Pushes a notification if the file data for that screen is empty (!shouldLoad(screenData)).\n  * Wraps deserialization and loading in a try / catch block to log and display an error message if parsing fails.\n5. Tests \u0026 Release Notes:\n  * Added tests in import_export_test.dart for missing activeScreenId and missing screen data.\n  * Added unit tests in performance_model_test.dart for OfflinePerformanceData.isEmpty.\n  * Created offline_data_test.dart testing OfflineScreenControllerMixin loading, empty payload notifications, and error handling.\n  * Documented the changes in NEXT_RELEASE_NOTES.md.\n\n* feedback\n\n* feedback",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "c37291140d6e76237a5c99969b001f19dbfbe3a6",
      "old_mode": 33188,
      "old_path": "packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_events_controller.dart",
      "new_id": "043bac512818130a531a8c4c556759b5447a6ae1",
      "new_mode": 33188,
      "new_path": "packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_events_controller.dart"
    },
    {
      "type": "modify",
      "old_id": "100eab0890291b9e5c6d10972684774117de3e40",
      "old_mode": 33188,
      "old_path": "packages/devtools_app/lib/src/screens/performance/performance_model.dart",
      "new_id": "84ce55a8457da9a60a760d28546a65eceb059195",
      "new_mode": 33188,
      "new_path": "packages/devtools_app/lib/src/screens/performance/performance_model.dart"
    },
    {
      "type": "modify",
      "old_id": "eed968af9613d877e706ea6ac4df509b5d388c29",
      "old_mode": 33188,
      "old_path": "packages/devtools_app/lib/src/shared/config_specific/import_export/import_export.dart",
      "new_id": "2f3f0e949fa24fedb84348824077f9cdd0cc36bc",
      "new_mode": 33188,
      "new_path": "packages/devtools_app/lib/src/shared/config_specific/import_export/import_export.dart"
    },
    {
      "type": "modify",
      "old_id": "c0be5799c330d2030ad93757289e8bfe2e97d961",
      "old_mode": 33188,
      "old_path": "packages/devtools_app/lib/src/shared/offline/offline_data.dart",
      "new_id": "6de315f6f9acea50f2b636cdaff0d307399c5900",
      "new_mode": 33188,
      "new_path": "packages/devtools_app/lib/src/shared/offline/offline_data.dart"
    },
    {
      "type": "modify",
      "old_id": "7e9c5050340034399c13a55fcae22353d41a7eaa",
      "old_mode": 33188,
      "old_path": "packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md",
      "new_id": "6462d13bf1239c6637d7aa4e61f85606d7e12bcd",
      "new_mode": 33188,
      "new_path": "packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md"
    },
    {
      "type": "modify",
      "old_id": "93da445100418ed89d97926a822cfbe9cefdd5b6",
      "old_mode": 33188,
      "old_path": "packages/devtools_app/test/screens/performance/performance_model_test.dart",
      "new_id": "9dc2a3f1dd0c9842599ef0d33cbed7e83dcceaa5",
      "new_mode": 33188,
      "new_path": "packages/devtools_app/test/screens/performance/performance_model_test.dart"
    },
    {
      "type": "modify",
      "old_id": "409531bfd3a6f87718fb1e48367c6b305a498a9f",
      "old_mode": 33188,
      "old_path": "packages/devtools_app/test/shared/import_export_test.dart",
      "new_id": "c723bb89e429b62e95e2ff07d14318839f05b186",
      "new_mode": 33188,
      "new_path": "packages/devtools_app/test/shared/import_export_test.dart"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "d0f08a810ba78b2388d93e4f820aa6b61620714b",
      "new_mode": 33188,
      "new_path": "packages/devtools_app/test/shared/offline/offline_data_test.dart"
    }
  ]
}
