{"record":{"id":"503b755b19b1b636","repo":"Universal-Debloater-Alliance/universal-android-debloater-next-generation","slug":"unable-to-parse","errorCode":null,"errorMessage":"Unable to parse","messagePattern":"Unable to parse","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/uad-core/src/uad_lists.rs","lineNumber":233,"sourceCode":"                    /universal-android-debloater\\\n                    /main\\\n                    /resources\\\n                    /assets\\\n                    /{LIST_FNAME}\"\n            ))\n            .call()\n            {\n                Ok(mut data) => {\n                    // https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/discussions/608\n                    let text = data\n                        .body_mut()\n                        .with_config()\n                        .limit(1 << (3 + 10 + 10))\n                        .read_to_string()\n                        .expect(\"remote list is bigger than 8MiB\");\n                    fs::write(cached_uad_lists.clone(), &text).expect(\"Unable to write file\");\n                    let list: PackageHashMap =\n                        serde_json::from_str(&text).expect(\"Unable to parse\");\n                    OperationResult::Ok(list)\n                }\n                Err(e) => {\n                    warn!(\"Could not load remote debloat list: {e}\");\n                    error = true;\n                    OperationResult::Retry(PackageHashMap::new())\n                }\n            }\n        })\n        .unwrap_or_else(|_| get_local_lists())\n    } else {\n        warn!(\"Could not load remote debloat list\");\n        get_local_lists()\n    };\n\n    (if error { Err } else { Ok })(list)\n}\n","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/64465c850c7ed36329e67165ac08501abffb218e/crates/uad-core/src/uad_lists.rs#L215-L251","documentation":"load_debloat_lists deserializes the freshly downloaded remote list text into PackageHashMap with `serde_json::from_str(&text).expect(\"Unable to parse\")`. If the downloaded body is not the expected JSON shape, this panics. The parse is the last trust boundary between the remote HTTP endpoint and the app's package metadata.","triggerScenarios":"load_debloat_lists succeeding at the HTTP GET but receiving non-JSON or wrong-schema JSON: the URL returns an HTML error/login page, a truncated body, a CDN 404 page, or the upstream list JSON schema changed incompatibly.","commonSituations":"Proxies or captive portals replacing the response; the remote list repository moved/renamed and the old URL now serves HTML; a partial/mirror copy of the list with malformed JSON; network cut mid-transfer producing truncated text.","solutions":["Replace .expect with error handling that returns OperationResult::Retry / falls back to get_local_lists, as the Err branch already does.","Validate the response content-type or a JSON sanity check (e.g. it starts with '{') before deserializing.","Fix the remote list URL to point at the official raw JSON endpoint.","Log the first bytes of the failing body to diagnose what was actually received."],"exampleFix":"// before\nlet list: PackageHashMap =\n    serde_json::from_str(&text).expect(\"Unable to parse\");\n// after\nlet list: PackageHashMap = serde_json::from_str(&text)\n    .unwrap_or_else(|e| {\n        warn!(\"Remote debloat list is invalid JSON: {e}\");\n        error = true;\n        PackageHashMap::new()\n    });","handlingStrategy":"fallback","validationCode":"let trimmed = text.trim_start();\nif !trimmed.starts_with('{') {\n    eprintln!(\"remote list did not return JSON (starts with {:?})\", &trimmed[..trimmed.len().min(20)]);\n}","typeGuard":null,"tryCatchPattern":"match serde_json::from_str::<PackageHashMap>(&text) {\n    Ok(list) => OperationResult::Ok(list),\n    Err(e) => { warn!(\"invalid remote list JSON: {e}\"); OperationResult::Retry(PackageHashMap::new()) }\n}","preventionTips":["Never deserialize an HTTP body without a fallback to the cached/bundled list.","Sanity-check the response body shape (first char, content-type) before parsing.","Beware proxies/captive portals replacing JSON responses with HTML."],"tags":["panic","json","parse-error","http"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"64465c850c7ed36329e67165ac08501abffb218e","analyzedAt":"2026-09-12T09:09:23.137Z","contentChangedAt":"2026-09-12T09:09:23.137Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}