{"record":{"id":"a1790b3751a7f3c7","repo":"Universal-Debloater-Alliance/universal-android-debloater-next-generation","slug":"there-must-be-at-least-1-separated-component","errorCode":null,"errorMessage":"There must be at least 1 ':'-separated component","messagePattern":"There must be at least 1 ':'-separated component","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/uad-core/src/adb.rs","lineNumber":418,"sourceCode":"                //let run;\n                let ln = if let Some(l) = ln.strip_suffix(\"running\") {\n                    //run = true;\n                    l.trim_ascii_end()\n                } else {\n                    //run = false;\n                    ln\n                };\n                let ln = ln.strip_suffix('}').unwrap_or(ln).trim_ascii_end();\n                // https://android.googlesource.com/platform/frameworks/base/+/refs/heads/main/core/java/android/content/pm/UserInfo.java\n                // The format looks stable today, but google may change it in future Android versions\n                // (and very old Androids might differ). Keep parsing defensive.\n                // Expected shape: \"UserInfo{<id>:<name>:<flags>}[ running]\"\n\n                let mut comps = ln.split(':');\n\n                let id = comps\n                    .next()\n                    .expect(\"There must be at least 1 ':'-separated component\")\n                    .parse()\n                    .expect(\"string assumed to be UID numeral\");\n                //let name = comps\n                //    .next()\n                //    .expect(\"There must be at least 2 ':'-separated components. 2nd is user-name\");\n                //let flags = u32::from_str_radix(\n                //    comps.next().expect(\n                //        \"There must be at least 3 ':'-separated components. 3rd is user bit-flags\",\n                //    ),\n                //    16,\n                //)\n                //.expect(\"string assumed to be hexadecimal bit-flags\");\n                UserInfo {\n                    id,\n                    //name: name.into(),\n                    //flags,\n                    //running: run,\n                }","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/64465c850c7ed36329e67165ac08501abffb218e/crates/uad-core/src/adb.rs#L400-L436","documentation":"list_users parses `adb shell pm list users` lines shaped like \"UserInfo{0:Owner:13}[ running]\" and splits on ':', expecting at least one component. If a line yields no first component (impossible for real input) the expect panics; effectively this fires when unexpected non-UserInfo lines reach the parser.","triggerScenarios":"Calling list_users() when adb output contains lines that pass the outer filter but lack the expected 'UserInfo{id:name:flags}' shape, e.g. empty/blank lines or warning text from adb shell.","commonSituations":"Non-standard Android ROMs altering pm list users format, adb daemon warnings inserted into output, OEM shells printing extra lines.","solutions":["Check `adb shell pm list users` raw output on the affected device for format deviations.","Ensure filtering only passes lines starting with 'UserInfo{' before parsing.","Update the app/library for ROMs with a different user-info format.","Patch to use if-let/next() with graceful skip instead of expect."],"exampleFix":"// before\nlet id = comps.next().expect(\"There must be at least 1 ':'-separated component\").parse().unwrap();\n// after\nlet Some(id) = comps.next().and_then(|c| c.trim().parse().ok()) else { continue; };","handlingStrategy":"validation","validationCode":"let output = std::process::Command::new(\"adb\").args([\"shell\", \"pm\", \"list\", \"users\"]).output()?;\nlet ok = String::from_utf8_lossy(&output.stdout)\n    .lines().any(|l| l.trim_start().starts_with(\"UserInfo{\"));","typeGuard":"fn is_user_info_line(line: &str) -> bool { line.trim_start().starts_with(\"UserInfo{\") }","tryCatchPattern":"let users = std::panic::catch_unwind(|| adb::list_users()).unwrap_or_else(|_| { eprintln!(\"unexpected pm list users output\"); Vec::new() });","preventionTips":["Filter to lines starting with 'UserInfo{' before parsing.","Check raw `adb shell pm list users` output when supporting new/OEM devices.","Trim and skip blank or warning lines from adb shell output.","Prefer Result-based parsing over expect in modified parsers."],"tags":["adb","parsing","panic","android"],"backgroundTag":"unexpected-response-shape","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"}