gitbutlerapp/gitbutler · error · napi::Error
argument ' ' must be a non-negative integer that fits in…
Error message
argument '{}' must be a non-negative integer that fits in usize What it means
The but_api macro converts napi integer parameters (i64/f64 on the JS side) into Rust usize via TryFrom. When the supplied value is negative or exceeds the platform usize range, the conversion fails and this InvalidArg error names the argument.
Solutions
- Clamp or validate the value to be a non-negative integer before the call
- Replace sentinel negative values with the API's explicit option (e.g. omit the parameter)
- Check the arithmetic upstream that produced the negative value
Example fix
// before api.listCommits(-10) // after api.listCommits(Math.max(0, offset))
Defensive patterns
Strategy: validation
Validate before calling
const isNonNegativeInt = (n) => Number.isInteger(n) && n >= 0;
Type guard
const isNonNegativeInt = (v: unknown): v is number => typeof v === 'number' && Number.isInteger(v) && v >= 0;
Try / catch
try { api.list(x); } catch (e) { if (/fits in usize/.test(e.message)) console.error('argument must be >= 0'); throw e; } Prevention
- Clamp computed indices/offsets with Math.max(0, value)
- Avoid -1 sentinels; use optional/omitted params instead
- Add range assertions in tests around pagination arithmetic
When it happens
Trigger: Calling a generated but_api NAPI function whose parameter is remapped to usize and passing a negative number, a value above usize::MAX (rare on 64-bit), or a non-integral JS number.
Common situations: Frontend computes a limit/offset/index that went negative (e.g. cursor - pageSize), or passes -1 as a sentinel 'unlimited' value which the API does not accept.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- argument ' ' must be an integer that fits in isize
- invalid ' ' at index
- Cannot cherry-pick above a reference
- Cannot derive a worktree directory from
- Cannot move branch onto itself
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/775918f01c2a50ee.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-api-macros/src/lib.rs:1661
names.push(ident.to_string());
conversions.push(quote! {
let #ident: crate::json::HexHash = ::std::str::FromStr::from_str(&#ident)
.map(crate::json::HexHash)
.map_err(|e: gix::hash::decode::Error| napi::Error::new(napi::Status::InvalidArg, format!("{e}")))?;
});
call_arg_idents.push(quote! { #ident });
}
_ => {
// For all other types: check for napi-incompatible types first
if let Some(napi_ty) = napi_type_remap(base_ty) {
// Type needs remapping (e.g., usize → i64)
params.push(quote! { #ident: #napi_ty });
names.push(ident.to_string());
let arg_name = ident.to_string();
let conversion = match type_name.as_deref() {
Some("usize") => quote! {
let #ident: usize = ::std::convert::TryFrom::try_from(#ident).map_err(|_| {
napi::Error::new(
napi::Status::InvalidArg,
format!(
"argument '{}' must be a non-negative integer that fits in usize",
#arg_name
),
)
})?;
},
Some("isize") => quote! {
let #ident: isize = ::std::convert::TryFrom::try_from(#ident).map_err(|_| {
napi::Error::new(
napi::Status::InvalidArg,
format!(
"argument '{}' must be an integer that fits in isize",
#arg_name
),
)
})?;View on GitHub (pinned to 58e5313667)