Skip to content

fix(ruvector-gnn): RuvectorLayer constructor panics instead of returning Result #216

@ruvnet

Description

@ruvnet

Summary

MultiHeadAttention::new() and RuvectorLayer::new() in ruvector-gnn use assert!() / panic!() for input validation instead of returning Result. When called from NAPI-RS or WASM bindings, this causes a fatal abort() that crashes the entire host process — no try/catch can intercept it.

Reproduction

const { RuvectorLayer } = require('@ruvector/gnn');

// This kills the process — no exception, just abort()
const layer = new RuvectorLayer(384, 128, 3, 0.1);
// hidden_dim=128 is NOT divisible by heads=3 → panic
thread '<unnamed>' panicked at crates/ruvector-gnn/src/layer.rs:97:9:
Embedding dimension must be divisible by number of heads
fatal runtime error: failed to initiate panic, error 5, aborting
Aborted (core dumped)

Root Cause

Two issues:

  1. Rust-side (crates/ruvector-gnn/src/layer.rs): MultiHeadAttention::new() uses assert!() instead of Result — panics across FFI boundary = process abort
  2. JS-side (downstream agentdb GNNService): passes config.layers (=3) as the heads parameter instead of config.heads, so 128 % 3 ≠ 0 triggers the panic

Fix

  • MultiHeadAttention::new() → returns Result<Self, GnnError>
  • RuvectorLayer::new() → returns Result<Self, GnnError>
  • All WASM/NAPI wrappers propagate errors as catchable JS exceptions
  • Also fixed pre-existing mmap.rs test compilation errors (grad_offset returns Option<usize>)

Affected Versions

  • @ruvector/gnn@0.1.24 (all platforms)
  • ruvector-gnn (Rust crate)

Impact

Surface Before After
Native Rust panic!() → process abort Err(GnnError::LayerConfig(...))
NAPI-RS (Node.js) abort() → uncatchable crash Catchable napi::Error
WASM WASM trap Catchable JsError

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions