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 Deno.dlopen(path, { symbols }), an entry with a type field declares a static data symbol to read from the library. "void" means 'no value', so a static of type void cannot be read; Deno rejects it while binding symbols. Function symbols (declared with parameters/result) are not affected.

Solutions

  1. Give the static symbol its real type ("u32", "pointer", ...) or delete the entry
  2. If the symbol is a function, declare it with parameters/result, not type
  3. For possibly-missing symbols, keep optional: true but with a valid type

Example fix

// before
const lib = Deno.dlopen("./lib.so", {
  version: { type: "void", name: "VERSION" },
});

// after
const lib = Deno.dlopen("./lib.so", {
  version: { type: "pointer", name: "VERSION" },
});
Defensive patterns

Strategy: validation

Validate before calling

function validateSymbols(symbols) {
  for (const [key, s] of Object.entries(symbols)) {
    if (s && "type" in s && s.type === "void") {
      throw new Error(`static symbol '${key}' cannot have type "void"`);
    }
  }
}

validateSymbols(symbols);
const lib = Deno.dlopen("./lib.so", symbols);

Prevention

When it happens

Trigger: Deno.dlopen("./lib.so", { handle: { type: "void", name: "handle" } }); bindings generated from C headers that emit void for globals; a function mistakenly declared with type instead of parameters/result.

Common situations: Auto-generated bindings from C headers; mixing up the static form ({ type }) and the function form ({ parameters, result }) of symbol declarations.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/5ba3c6e0f522e872. Report an issue: GitHub.

Appendix: 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 9ad36f7a2c)