{"record":{"id":"c61ac631c8ed6eb0","repo":"can1357/oh-my-pi","slug":"err-to-string-size-parse-error","errorCode":null,"errorMessage":"err.to_string() (size parse error)","messagePattern":"err\\.to_string\\(\\) \\(size parse error\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/pi-builtins/src/fd.rs","lineNumber":1311,"sourceCode":"\nfn parse_size_filter(value: &str) -> io::Result<SizeFilter> {\n\tlet (ordering, rest) = if let Some(rest) = value.strip_prefix('+') {\n\t\t(SizeOrdering::GreaterOrEqual, rest)\n\t} else if let Some(rest) = value.strip_prefix('-') {\n\t\t(SizeOrdering::LessOrEqual, rest)\n\t} else {\n\t\t(SizeOrdering::Equal, value)\n\t};\n\tlet split = rest\n\t\t.char_indices()\n\t\t.find(|(_, ch)| !ch.is_ascii_digit())\n\t\t.map_or(rest.len(), |(index, _)| index);\n\tif split == 0 {\n\t\treturn Err(io::Error::new(io::ErrorKind::InvalidInput, format!(\"invalid size: {value}\")));\n\t}\n\tlet count = rest[..split]\n\t\t.parse::<u64>()\n\t\t.map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err.to_string()))?;\n\tlet unit = rest[split..].to_ascii_lowercase();\n\tlet multiplier = match unit.as_str() {\n\t\t\"\" | \"b\" => 1,\n\t\t\"k\" => 1_000,\n\t\t\"m\" => 1_000_000,\n\t\t\"g\" => 1_000_000_000,\n\t\t\"t\" => 1_000_000_000_000,\n\t\t\"ki\" => 1_024,\n\t\t\"mi\" => 1_048_576,\n\t\t\"gi\" => 1_073_741_824,\n\t\t\"ti\" => 1_099_511_627_776,\n\t\t_ => {\n\t\t\treturn Err(io::Error::new(\n\t\t\t\tio::ErrorKind::InvalidInput,\n\t\t\t\tformat!(\"invalid size unit: {unit}\"),\n\t\t\t));\n\t\t},\n\t};","sourceCodeStart":1293,"sourceCodeEnd":1329,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/crates/pi-builtins/src/fd.rs#L1293-L1329","documentation":"After the digit run is extracted, it is parsed with u64::from_str. If the digit run is longer than 20 digits or otherwise exceeds the u64 range (18446744073709551615), the parse fails and the underlying ParseIntError message ('number too large to fit in target type') is wrapped into an io::Error with ErrorKind::InvalidInput. Note this fires only for the raw count overflow; a valid count times a large unit takes the separate 'size is too large' path.","triggerScenarios":"Passing a --size value whose digit portion exceeds u64::MAX, e.g. '99999999999999999999999b' (23 digits). Any value with more than 20 digits, or exactly u64::MAX+1 like '18446744073709551616'.","commonSituations":"Accidentally pasting a byte offset or ID into a size flag; a script concatenating values producing an absurdly long number; fat-fingered repeated digits; locale-formatted sizes with digit-group separators are impossible here but a long unseparated string is a common paste artifact.","solutions":["Reduce the digit count to fit u64 (≤20 digits) — for practical sizes use a unit: '99999999999t' instead of a 23-digit byte count","Inspect the interpolated value in scripts to ensure no extra digits were concatenated","Use a unit multiplier (k/m/g/t) rather than spelling out huge byte counts","Catch the io::Error and validate size strings with a regex like ^[+-]?\\d+[a-z]*$ plus a u64 range check before calling"],"exampleFix":"// before\nfd --size '99999999999999999999999b'\n// after\nfd --size '100t'  // 100 terabytes, fits u64","handlingStrategy":"validation","validationCode":"function validateSizeCount(value: string): string | null {\n  const digits = value.replace(/^[+-]/, \"\").match(/^\\d+/)?.[0] ?? \"\";\n  if (digits.length > 20) return `size count too large for u64: ${value}`;\n  if (digits.length === 20 && digits > \"18446744073709551615\") return `size count exceeds u64::MAX: ${value}`;\n  return null;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await runFd({ size: value });\n} catch (err) {\n  if (err instanceof Error && /number too large to fit in target type/.test(err.message)) {\n    console.error(`Count exceeds u64 (max 18446744073709551615): ${value}. Use a larger unit.`);\n  } else throw err;\n}","preventionTips":["Cap digit runs at 20 characters in scripts that generate size filters","Prefer unit-suffixed sizes (100t) over spelled-out byte counts","When formatting from float math, round and cap instead of emitting full precision","Remember the raw count itself must fit u64 before any unit multiplier is applied"],"tags":["cli","size-parsing","integer-overflow","invalid-input"],"backgroundTag":"number-out-of-range","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}