RightNow-AI/openfang · error · SandboxError

host_call: request out of bounds

Error message

host_call: request out of bounds

What it means

The WASM guest module called the host function openfang.host_call with a (request_ptr, request_len) pair whose byte range [ptr, ptr+len) extends past the end of the guest's linear memory. The host refuses to read out-of-bounds memory rather than trap or read garbage, so it fails the call with this error. It is a guest-side ABI/pointer bug surfaced through the host.

Source

Thrown at crates/openfang-runtime/src/sandbox.rs:307

        linker
            .func_wrap(
                "openfang",
                "host_call",
                |mut caller: Caller<'_, GuestState>,
                 request_ptr: i32,
                 request_len: i32|
                 -> Result<i64, Error> {
                    // Read request from guest memory
                    let memory = caller
                        .get_export("memory")
                        .and_then(|e| e.into_memory())
                        .ok_or_else(|| format_err!("no memory export"))?;

                    let data = memory.data(&caller);
                    let start = request_ptr as usize;
                    let end = start + request_len as usize;
                    if end > data.len() {
                        bail!("host_call: request out of bounds");
                    }
                    let request_bytes = data[start..end].to_vec();

                    // Parse request
                    let request: serde_json::Value = serde_json::from_slice(&request_bytes)?;
                    let method = request
                        .get("method")
                        .and_then(|m| m.as_str())
                        .unwrap_or("")
                        .to_string();
                    let params = request
                        .get("params")
                        .cloned()
                        .unwrap_or(serde_json::Value::Null);

                    // Dispatch to capability-checked handler
                    let response = host_functions::dispatch(caller.data(), &method, &params);

View on GitHub (pinned to acf2587e46)

Solutions

  1. Fix the guest code so the pointer/length describe a valid in-bounds region: verify ptr and len are the exact values returned by the guest alloc call for the serialized request buffer
  2. Check that request_len is a byte length (use the serialized JSON's len(), not an element count) and that the buffer was not freed or overwritten before calling host_call
  3. Ensure the guest module exports a 'memory' export whose size actually covers the buffer (call memory.grow if needed before writing)
  4. Add a guest-side bounds assertion (ptr + len <= memory size) before invoking host_call so the failure is caught inside the module with better diagnostics
  5. Rebuild the guest to the current openfang guest ABI and re-run; stale prebuilt .wasm binaries often carry old struct layouts

Example fix

// before (guest Rust, len in elements)
let ptr = alloc(request.len() as i32);
host_call(ptr as i32, request.len() as i32);
// after (len in bytes of the serialized buffer)
let bytes = serde_json::to_vec(&request).unwrap();
let ptr = alloc(bytes.len() as i32);
unsafe { core::slice::from_raw_parts_mut(ptr as *mut u8, bytes.len()) }.copy_from_slice(&bytes);
host_call(ptr as i32, bytes.len() as i32);
Defensive patterns

Strategy: try-catch

Validate before calling

// guest-side, before calling host_call
let mem_size = memory.size(&store) as usize * 65536;
let (start, len) = (request_ptr as usize, request_len as usize);
assert!(start.checked_add(len).is_some() && start + len <= mem_size, "request buffer out of bounds");

Type guard

fn in_bounds(ptr: i32, len: i32, mem_len: usize) -> bool {
    ptr >= 0 && len >= 0 && (ptr as u64) + (len as u64) <= mem_len as u64
}

Try / catch

// guest module call, catch the trap/error from host_call
match sandbox.call(&input) {
    Err(e) if e.to_string().contains("request out of bounds") => {
        eprintln!("guest ABI bug: bad request_ptr/request_len: {e}");
        // recompile/fix guest, do not retry blindly
    }
    r => r?,
}

Prevention

When it happens

Trigger: Calling host_call with a pointer or length computed incorrectly in the guest: wrong endianness or negative i32 cast to usize, a stale pointer into a region already freed/reclaimed by the guest allocator, an oversized request_len, or a guest module whose memory shrinks via memory.grow/replace semantics.

Common situations: Hand-written guest bindings in Rust/C/WASM modules; a custom allocator returning bogus pointers (e.g. forgetting to grow memory before alloc); passing a length in bytes vs elements; forgetting the 4GB usize cast wraps for negative pointers; guests built against a different ABI version than the host linker expects.

Related errors


AI-assisted analysis of RightNow-AI/openfang@acf2587e46 (2026-09-02). Data as JSON: /api/errors/7f4d2a166f388fa0. Report an issue: GitHub.