RightNow-AI/openfang · error · SandboxError
host_call: response exceeds memory bounds
Error message
host_call: response exceeds memory bounds
What it means
When the guest invokes host_call, the host serializes the response, asks the guest's exported alloc() for a destination buffer, then copies the response JSON into guest memory. If the returned pointer plus the response length exceeds the guest linear memory size, the host bails instead of writing out of bounds. This usually means the guest's alloc function returned an invalid pointer or did not reserve enough space.
Source
Thrown at crates/openfang-runtime/src/sandbox.rs:347
// Allocate space in guest for response
let alloc_fn = caller
.get_export("alloc")
.and_then(|e| e.into_func())
.ok_or_else(|| format_err!("no alloc export"))?;
let alloc_typed = alloc_fn.typed::<i32, i32>(&caller)?;
let ptr = alloc_typed.call(&mut caller, len)?;
// Write response into guest memory
let memory = caller
.get_export("memory")
.and_then(|e| e.into_memory())
.ok_or_else(|| format_err!("no memory export"))?;
let mem_data = memory.data_mut(&mut caller);
let dest_start = ptr as usize;
let dest_end = dest_start + response_bytes.len();
if dest_end > mem_data.len() {
bail!("host_call: response exceeds memory bounds");
}
mem_data[dest_start..dest_end].copy_from_slice(&response_bytes);
// Pack (ptr, len) into i64
Ok(((ptr as i64) << 32) | (len as i64))
},
)
.map_err(|e| SandboxError::Compilation(e.to_string()))?;
// host_log: lightweight logging — no capability check required.
linker
.func_wrap(
"openfang",
"host_log",
|mut caller: Caller<'_, GuestState>,
level: i32,
msg_ptr: i32,
msg_len: i32|View on GitHub (pinned to acf2587e46)
Solutions
- Fix the guest alloc export to return a valid, suitably sized region: reserve at least the requested size and grow memory (memory.grow) when the current allocation area cannot fit it
- Verify alloc returns a raw byte pointer, not a handle or offset relative to a heap base, matching the openfang guest ABI
- If the response is legitimately large, grow the guest's linear memory (compile with a larger --initial-memory or call memory.grow before host_call)
- Test the guest with a worst-case-size response from dispatch to catch the failure during development, not production
- Add a guest-side post-alloc check that ptr + size <= memory.size()*64KiB and fail fast with a clear trap
Example fix
// before (guest alloc that never grows memory)
pub extern "C" fn alloc(size: i32) -> i32 { HEAP_BASE + offset } // can overflow linear memory
// after
pub extern "C" fn alloc(size: i32) -> i32 {
if HEAP_BASE + offset + size > mem_size() { grow_memory(size); }
HEAP_BASE + offset
} Defensive patterns
Strategy: validation
Validate before calling
// guest-side, after alloc and before host_call let mem_size = memory.size() * 65536; assert!(ptr >= 0 && (ptr as u64) + response_bytes.len() as u64 <= mem_size as u64, "alloc returned invalid region");
Type guard
fn alloc_result_ok(ptr: i32, need: usize, mem_len: usize) -> bool {
ptr >= 0 && (ptr as u64).checked_add(need as u64).map_or(false, |end| end <= mem_len as u64)
} Try / catch
match result {
Err(e) if e.to_string().contains("response exceeds memory bounds") => {
eprintln!("guest alloc returned too-small/invalid region: {e}");
// grow guest memory or fix alloc(); retry once after fix
}
other => other?,
} Prevention
- Implement alloc to honor its size parameter and memory.grow when the heap is exhausted
- Test guests with maximum-size responses, not just toy payloads
- Return raw byte pointers from alloc per the openfang ABI, not handles/offsets
- Keep a headroom test: allocate a response near the memory limit in CI
- Log alloc(ptr, size) results in debug builds to catch bogus pointers early
When it happens
Trigger: The guest alloc() returns a pointer near the end of linear memory without growing memory; alloc ignores its size argument; alloc is missing/buggy in a hand-written guest; the response payload is large and the guest memory was not grown; pointer arithmetic in the guest wraps (i32 overflow).
Common situations: Custom guest runtimes with minimal allocators that return fixed offsets; responses that grew after an API change (bigger JSON payloads) while the guest heap did not; guests compiled for a different ABI where alloc returns a tagged/handle value instead of a raw pointer; running with a reduced initial memory limit in the sandbox config.
Related errors
AI-assisted analysis of RightNow-AI/openfang@acf2587e46 (2026-09-02).
Data as JSON: /api/errors/191c89d416ce111d.
Report an issue: GitHub.