napi-rs/napi-rs · error

InvalidArg

InvalidArg

Error message

referenced ptr is null

What it means

This is a codegen-injected guard: when generated #[napi] function argument conversion needs to take a reference to an argument (make_ref), it checks the raw pointer for null and throws InvalidArg 'referenced ptr is null' if it is null. Hitting it means a required reference argument arrived as a null raw pointer, which the generated code refuses to reference.

Solutions

  1. Pass a real, non-null value for the argument instead of null/undefined
  2. Check the generated .d.ts signature and supply all required reference arguments
  3. If the argument is optional in your design, change the Rust signature to Option<T> so null is handled
  4. Regenerate bindings if the addon was rebuilt with a different signature

Example fix

// before
mod.doWork(null) // ptr is null -> InvalidArg
// after
mod.doWork({ id: 1 })
Defensive patterns

Strategy: validation

Validate before calling

function requireRef(v, name) { if (v === null || v === undefined) throw new TypeError(name + ' must be a non-null object'); return v }

Type guard

const isNonNullObject = (v) => v !== null && (typeof v === 'object' || typeof v === 'function')

Try / catch

try {
  addon.fn(arg)
} catch (e) {
  if (e.code === 'InvalidArg' && /referenced ptr is null/.test(e.message)) {
    throw new TypeError('arg must not be null/undefined')
  }
  throw e
}

Prevention

When it happens

Trigger: Calling a generated napi function whose argument conversion uses make_ref with a null/undefined or otherwise null-backed value where a non-null reference is required (e.g. passing null for an argument typed as an object/class reference in a generated binding).

Common situations: Calling a native addon function with null/undefined for an argument expected to be a real object; FFI-level misuse where a pointer field was never populated; mismatches between generated bindings and the JS values passed.

Related errors


AI-assisted analysis of napi-rs/napi-rs@39bd1205e4 (2026-09-13). Data as JSON: /api/errors/889493ff38340c55. Report an issue: GitHub.

Appendix: source

Thrown at crates/backend/src/codegen/fn.rs:1080

          }
        }
      }
    }
    Type::Reference(TypeReference {
      lifetime: Some(lt), ..
    }) => {
      *lt = syn::Lifetime::new("'_", Span::call_site());
    }
    _ => {}
  }
  Ok(())
}

fn make_ref(input: TokenStream) -> TokenStream {
  quote! {
    _args_array[_arg_write_index] = _make_ref(
      ::std::ptr::NonNull::new(#input)
        .ok_or_else(|| napi::Error::new(napi::Status::InvalidArg, "referenced ptr is null".to_owned()))?
    )?;
    _arg_write_index += 1;
  }
}

struct ArgConversions {
  pub args: Vec<TokenStream>,
  pub arg_conversions: Vec<TokenStream>,
  pub this_conversions: Vec<TokenStream>,
  pub receiver_unwrap: TokenStream,
  pub receiver_dependent_conversions: Vec<TokenStream>,
  pub receiver_conversion: TokenStream,
  pub refs: Vec<TokenStream>,
  pub mut_ref_spans: Vec<Span>,
  pub unsafe_: bool,
}

#[derive(Debug, PartialEq, Eq)]

View on GitHub (pinned to 39bd1205e4)