wasmerio/wasmer · error
Unable to cast to a {}
Error message
Unable to cast to a {} What it means
js_array in lib/wasix/src/http/web_http_client.rs converts a JS array-like (e.g. the result of Array.from(headers)) into a fixed-size Rust array [T; N] by dyn_into-casting each element. If any element is not actually of type T (expected pairs of [name, value] arrays but found something else), the dyn_into fails and this error names the expected Rust type.
Source
Thrown at lib/wasix/src/http/web_http_client.rs:263
header_map.insert(key, value);
}
Ok(header_map)
}
fn js_array<T, const N: usize>(value: &JsValue) -> Result<[T; N], anyhow::Error>
where
T: JsCast,
{
let array: &js_sys::Array = value.dyn_ref().context("Not an array")?;
let mut items = Vec::new();
for value in array.iter() {
let item = value
.dyn_into()
.map_err(|_| anyhow::anyhow!("Unable to cast to a {}", std::any::type_name::<T>()))?;
items.push(item);
}
<[T; N]>::try_from(items).map_err(|original| {
anyhow::anyhow!(
"Unable to turn a list of {} items into an array of {N} items",
original.len()
)
})
}
pub async fn get_response_data(resp: &web_sys::Response) -> Result<Vec<u8>, anyhow::Error> {
let buffer = JsFuture::from(resp.array_buffer().unwrap())
.await
.map_err(js_error)
.with_context(|| "Could not retrieve response body".to_string())?;
let buffer = js_sys::Uint8Array::new(&buffer);View on GitHub (pinned to 8c4b9ee9d3)
Solutions
- Check the inner JS environment: run in a standard browser with native Headers support, not a partial polyfill.
- Log/inspect the raw JS array before conversion to see the actual element shape.
- Ensure the response/request headers are plain string-to-string pairs; convert non-string values with String() on the JS side.
- Update the CLI/runtime — host binding mismatches between JS glue and Rust expectations are often fixed upstream.
- If you control the JS glue, normalize entries to [string, string] arrays before passing them across the boundary.
Example fix
// before (JS glue passes headers entries verbatim) const entries = headers.entries(); fetchBytes(entries); // after: normalize to [string, string] pairs const entries = Array.from(headers.entries()) .map(([k, v]) => [String(k), String(v)]) .filter(([k, v]) => k != null && v != null); fetchBytes(entries);
Defensive patterns
Strategy: type-guard
Validate before calling
// normalize the JS array shape before it reaches js_array
const entries = Array.from(headers.entries())
.filter(e => Array.isArray(e) && e.length === 2
&& typeof e[0] === 'string' && typeof e[1] === 'string')
.map(([k, v]) => [String(k), String(v)]); Type guard
// Rust-side narrowing check before dyn_into
fn is_js_string_pair(v: &JsValue) -> bool {
js_sys::Array::is_array(v)
&& js_sys::Array::from(v).length() == 2
&& js_sys::Array::from(v).get(0).is_string()
&& js_sys::Array::from(v).get(1).is_string()
} Try / catch
match headers(client).await {
Err(e) if e.to_string().contains("Unable to cast to a") => {
eprintln!("{e}\nHint: JS headers entries are not [string, string] pairs — normalize on the JS side or update the runtime");
std::process::exit(1);
}
other => other,
} Prevention
- Test in a standard browser with native Headers support before exotic environments
- Coerce header keys/values to strings on the JS side before crossing the wasm boundary
- Keep the JS glue and Rust runtime versions in sync
- Log raw JS values when debugging bridging failures instead of guessing the shape
When it happens
Trigger: The JS value iterated in `headers` contains elements that don't match the expected shape — e.g. Headers.entries() returned items that aren't length-2 string arrays, or the JS bridge returned objects instead of arrays.
Common situations: Running in a JS environment whose Headers implementation returns non-standard iteration results (polyfills, workers, Node vs browser differences); a header entry containing null/undefined values; mismatch between expected tuple arity and what the host returns.
Related errors
- Could not apply request header: '{name}': '{value}'
- Exception handling is not yet supported in js
- cloning JavaScript shared memory should not fail
- unimplemented operator {operator:?}
- global #{} is a constant
AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01).
Data as JSON: /api/errors/07f117cccab1cabe.
Report an issue: GitHub.