{"record":{"id":"d1d17461d5125c78","repo":"can1357/oh-my-pi","slug":"owner-filters-in-the-in-process-fd-builtin-require","errorCode":null,"errorMessage":"owner filters in the in-process fd builtin require numeric uid/gid values","messagePattern":"owner filters in the in-process fd builtin require numeric uid/gid values","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/pi-builtins/src/fd.rs","lineNumber":1458,"sourceCode":"\t\t.collect()\n}\n\nfn parse_owner_filter(value: &str) -> io::Result<OwnerMatcher> {\n\tlet (user, group) = value.split_once(':').unwrap_or((value, \"\"));\n\tOk(OwnerMatcher { user: parse_owner_side(user)?, group: parse_owner_side(group)? })\n}\n\nfn parse_owner_side(value: &str) -> io::Result<Option<OwnerSide>> {\n\tif value.is_empty() {\n\t\treturn Ok(None);\n\t}\n\tlet (exclude, raw) = if let Some(raw) = value.strip_prefix('!') {\n\t\t(true, raw)\n\t} else {\n\t\t(false, value)\n\t};\n\tlet id = raw.parse::<u32>().map_err(|_| {\n\t\tio::Error::new(\n\t\t\tio::ErrorKind::InvalidInput,\n\t\t\t\"owner filters in the in-process fd builtin require numeric uid/gid values\",\n\t\t)\n\t})?;\n\tOk(Some(if exclude {\n\t\tOwnerSide::Exclude(id)\n\t} else {\n\t\tOwnerSide::Include(id)\n\t}))\n}\n\nfn match_target(path: &Path, base_dir: &Path, full_path: bool) -> String {\n\tif full_path {\n\t\treturn normalize_display_path(path);\n\t}\n\tpath.file_name().map_or_else(\n\t\t|| normalize_display_path(path.strip_prefix(base_dir).unwrap_or(path)),\n\t\tnormalize_os_str,","sourceCodeStart":1440,"sourceCodeEnd":1476,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/crates/pi-builtins/src/fd.rs#L1440-L1476","documentation":"The in-process fd builtin's owner filter accepts only numeric uid/gid values. When parsing the filter value (after optional '!' negation prefix) as u32 fails, this InvalidInput error explains that owner filters require numeric uid/gid values rather than names like 'root' or 'alice'.","triggerScenarios":"Calling the builtin with an owner filter option set to a username or group name (e.g. 'owner=root' or 'owner=!root') instead of a numeric id such as '0' or '1000'; also empty strings or values containing non-digit characters.","commonSituations":"Scripts copying the CLI's name-based owner filtering behavior into the SDK/embedded call, where only numeric ids are supported; hard-coded names in config; resolving a user by name without calling libc getpwnam first.","solutions":["Resolve the username to a numeric uid (e.g. via a getpwuid/getpwnam lookup or `id -u <name>`) before passing the filter","Pass the raw numeric uid/gid string, e.g. '0' for root","Keep the '!' prefix if negation is desired, e.g. '!0' to exclude uid 0"],"exampleFix":"// before\nlet filter = OwnerFilter::parse(\"root\");\n// after\nlet uid = /* resolve via passwd lookup */ 0u32;\nlet filter = OwnerFilter::parse(&uid.to_string());","handlingStrategy":"validation","validationCode":"fn validate_owner_filter(value: &str) -> Result<(), String> {\n\tlet raw = value.strip_prefix('!').unwrap_or(value);\n\tif raw.parse::<u32>().is_err() {\n\t\treturn Err(format!(\"owner filter must be numeric uid/gid, got '{raw}'\"));\n\t}\n\tOk(())\n}","typeGuard":null,"tryCatchPattern":"match builtin_result {\n\tErr(e) if e.to_string().contains(\"numeric uid/gid\") => eprintln!(\"resolve user/group names to ids first: {e}\"),\n\tErr(e) => return Err(e),\n\tOk(v) => /* ... */,\n}","preventionTips":["Resolve user/group names to numeric ids via passwd/group lookups before invoking the embedded builtin","Remember the '!' prefix only negates; it does not enable name lookup","Store uids, not usernames, in configs consumed by the embedded fd builtin"],"tags":["rust","io","argument-parsing","owner-filter"],"backgroundTag":"numeric-id-required","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}