Universal-Debloater-Alliance/universal-android-debloater-next-generation · error

string assumed to be UID numeral

Error message

string assumed to be UID numeral

What it means

In list_users, the first ':'-separated component of a UserInfo line is parsed as the numeric user ID; if parse() fails, expect panics with "string assumed to be UID numeral". The library assumes adb always reports a decimal UID in the first field.

Solutions

  1. Re-run `adb shell pm list users` to rule out truncated/corrupt output.
  2. Inspect the offending line and confirm it matches UserInfo{<int>:...}.
  3. Replace the device or update its ROM/Android version if the format is non-standard.
  4. Patch parsing to fall back gracefully (e.g. .ok() and skip the line) instead of expect.

Example fix

// before
.parse().expect("string assumed to be UID numeral")
// after
let id: u32 = comps.next()?.trim().parse().ok()?; // skip line on parse failure
Defensive patterns

Strategy: validation

Validate before calling

let first = line.trim_start().trim_start_matches("UserInfo{");
let id_str = first.split(':').next().unwrap_or("");
if id_str.parse::<u32>().is_err() { return Err(format!("non-numeric user id: {id_str:?}")); }

Type guard

fn parse_user_id(seg: &str) -> Option<u32> { seg.trim().parse::<u32>().ok() }

Try / catch

let users = std::panic::catch_unwind(|| adb::list_users()).unwrap_or_else(|_| { eprintln!("user id parse failed; check device output"); Vec::new() });

Prevention

When it happens

Trigger: Calling list_users() when the id field of a UserInfo line is not a valid integer — malformed or truncated adb output, or a ROM emitting a different UserInfo format where the first segment is non-numeric.

Common situations: Truncated output over a flaky USB/wireless adb connection, modified pm binary, localized or OEM-altered user listings.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of Universal-Debloater-Alliance/universal-android-debloater-next-generation@64465c850c (2026-09-12). Data as JSON: /api/errors/6125c237f1f3c047. Report an issue: GitHub.

Appendix: source

Thrown at crates/uad-core/src/adb.rs:420

                    //run = true;
                    l.trim_ascii_end()
                } else {
                    //run = false;
                    ln
                };
                let ln = ln.strip_suffix('}').unwrap_or(ln).trim_ascii_end();
                // https://android.googlesource.com/platform/frameworks/base/+/refs/heads/main/core/java/android/content/pm/UserInfo.java
                // The format looks stable today, but google may change it in future Android versions
                // (and very old Androids might differ). Keep parsing defensive.
                // Expected shape: "UserInfo{<id>:<name>:<flags>}[ running]"

                let mut comps = ln.split(':');

                let id = comps
                    .next()
                    .expect("There must be at least 1 ':'-separated component")
                    .parse()
                    .expect("string assumed to be UID numeral");
                //let name = comps
                //    .next()
                //    .expect("There must be at least 2 ':'-separated components. 2nd is user-name");
                //let flags = u32::from_str_radix(
                //    comps.next().expect(
                //        "There must be at least 3 ':'-separated components. 3rd is user bit-flags",
                //    ),
                //    16,
                //)
                //.expect("string assumed to be hexadecimal bit-flags");
                UserInfo {
                    id,
                    //name: name.into(),
                    //flags,
                    //running: run,
                }
            })
            .collect())

View on GitHub (pinned to 64465c850c)