denoland/deno · error · TypeError
Foreign symbol of type 'void' is not supported
Error message
Foreign symbol of type 'void' is not supported
What it means
In the Deno.dlopen symbol table, an entry carrying a `type` field requests a static value read from the loaded library (op_ffi_get_static) — i.e. an exported data symbol. 'void' denotes no value at all, so it is rejected up front with a TypeError. Function symbols use { parameters, result } instead and never take a `type` field.
Source
Thrown at ext/ffi/00_ffi.js:477
symbols = { __proto__: null };
constructor(path, symbols) {
({ 0: this.#rid, 1: this.symbols } = op_ffi_load(path, symbols));
for (const symbol in symbols) {
if (!ObjectHasOwn(symbols, symbol)) {
continue;
}
// Symbol was marked as optional, and not found.
// In that case, we set its value to null in Rust-side.
if (symbols[symbol] === null) {
continue;
}
if (ReflectHas(symbols[symbol], "type")) {
const type = symbols[symbol].type;
if (type === "void") {
throw new TypeError(
"Foreign symbol of type 'void' is not supported",
);
}
const name = symbols[symbol].name || symbol;
const value = op_ffi_get_static(
this.#rid,
name,
type,
symbols[symbol].optional,
);
ObjectDefineProperty(
this.symbols,
symbol,
{
__proto__: null,
configurable: false,
enumerable: true,View on GitHub (pinned to 89f33cbef2)
Solutions
- Delete the symbol entry (or its type field) instead of stubbing it with void
- Use the real C type of the exported datum: u32, i32, f64, pointer, etc.
- For exported functions, declare { parameters: [...], result: ... } rather than { type: ... }
- Use optional: true only for symbols that may be missing in the library, not as a substitute for a valid type
Example fix
// before
const lib = Deno.dlopen("./libexample.so", {
VERSION: { name: "VERSION", type: "void" },
});
// after
const lib = Deno.dlopen("./libexample.so", {
VERSION: { name: "VERSION", type: "u32" }, // actual C type of the exported variable
}); Defensive patterns
Strategy: validation
Validate before calling
const VALID_STATIC_TYPES = new Set(["u8","u16","u32","u64","i8","i16","i32","i64","f32","f64","usize","isize","pointer"]);
function validateStaticSymbols(symbols) {
for (const [key, def] of Object.entries(symbols)) {
if (def && typeof def === "object" && "type" in def && !VALID_STATIC_TYPES.has(def.type)) {
throw new Error(`symbol '${key}' has unsupported static type '${def.type}'`);
}
}
}
validateStaticSymbols(symbols);
const lib = Deno.dlopen(path, symbols); Type guard
const VALID_STATIC_TYPES = new Set(["u8","u16","u32","u64","i8","i16","i32","i64","f32","f64","usize","isize","pointer"]);
function isStaticSymbolDef(def: unknown): boolean {
return typeof def === "object" && def !== null && "type" in def &&
VALID_STATIC_TYPES.has((def as { type: string }).type);
} Try / catch
try {
lib = Deno.dlopen(path, symbols);
} catch (err) {
if (err instanceof TypeError && err.message === "Foreign symbol of type 'void' is not supported") {
// drop or retype the void entry (it names a data symbol with no value)
} else throw err;
} Prevention
- Only give `type` to exported data symbols, with their real C type
- Declare functions as { parameters: [...], result: ... } instead of { type }
- Sanitize generated bindings before dlopen instead of feeding headers verbatim
- Use optional: true for possibly-missing symbols, never 'void' as a placeholder
When it happens
Trigger: Deno.dlopen(lib, { VERSION: { name: "VERSION", type: "void" } }) — any symbol object whose type is exactly "void".
Common situations: Auto-generated binding files from C headers that include void macros or placeholder entries; misunderstanding that `type` is for exported variables; hand-writing a stub entry to 'skip' a symbol.
Related errors
- Cannot access pointer: expected 'ArrayBuffer', 'SharedArrayB
- Cannot get pointer size: found recursive struct
- Cannot get pointer size, unsupported type: ${type}
- Cannot construct UnsafeCallback: cannot be nonblocking
- Cannot convert a Symbol value to a string
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/5ba3c6e0f522e872.
Report an issue: GitHub.