denoland/deno · error · TypeError

Cannot get pointer size, unsupported type: ${type}

Error message

Cannot get pointer size, unsupported type: ${type}

What it means

When FFI needs the size/alignment of a type (for example struct layout in UnsafeFnPointer), getTypeSizeAndAlignment switches over the supported scalar names: fixed-width integers (u8/u16/u32/u64, i8/i16/i32/i64), floats (f32/f64), and 8-byte types (pointer, buffer, function, usize, isize), plus struct objects. An unrecognized string reaches the default arm and throws a TypeError echoing the offending type.

Source

Thrown at ext/ffi/00_ffi.js:390

      return [1, 1];
    case "u16":
    case "i16":
      return [2, 2];
    case "u32":
    case "i32":
    case "f32":
      return [4, 4];
    case "u64":
    case "i64":
    case "f64":
    case "pointer":
    case "buffer":
    case "function":
    case "usize":
    case "isize":
      return [8, 8];
    default:
      throw new TypeError(`Cannot get pointer size, unsupported type: ${type}`);
  }
}

class UnsafeCallback {
  #refcount;
  // Internal promise only meant to keep Deno from exiting
  #refpromise;
  #rid;
  definition;
  callback;
  pointer;

  constructor(definition, callback) {
    if (definition.nonblocking) {
      throw new TypeError(
        "Cannot construct UnsafeCallback: cannot be nonblocking",
      );
    }

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Map C names to FFI names: size_t/uintptr_t -> "usize", char* -> "pointer", float -> "f32", double -> "f64"
  2. Use only the supported set: u8/u16/u32/u64, i8/i16/i32/i64, f32/f64, usize/isize, pointer, buffer, function, or { struct: [...] }
  3. Find the exact bad string from the error message and grep your type definitions for it

Example fix

// before
const def = { parameters: ["size_t"], result: "void" }; // unsupported type: size_t

// after
const def = { parameters: ["usize"], result: "void" };
Defensive patterns

Strategy: type-guard

Validate before calling

const FFI_SCALARS = new Set(["u8","u16","u32","u64","i8","i16","i32","i64","f32","f64","usize","isize","pointer","buffer","function","void"]);
function assertValidTypes(t, path = "root") {
  if (typeof t === "string") {
    if (!FFI_SCALARS.has(t)) throw new Error(`invalid FFI type '${t}' at ${path}`);
  } else if (t && typeof t === "object" && Array.isArray(t.struct)) {
    t.struct.forEach((f, i) => assertValidTypes(f, `${path}.struct[${i}]`));
  } else {
    throw new Error(`invalid FFI type node at ${path}`);
  }
}

Type guard

const FFI_SCALARS = new Set(["u8","u16","u32","u64","i8","i16","i32","i64","f32","f64","usize","isize","pointer","buffer","function","void"]);
function isFfiTypeNode(t: unknown): boolean {
  if (typeof t === "string") return FFI_SCALARS.has(t);
  return typeof t === "object" && t !== null && Array.isArray((t as { struct?: unknown[] }).struct);
}

Try / catch

try {
  const fn = new Deno.UnsafeFnPointer(ptr, definition);
} catch (err) {
  if (err instanceof TypeError && err.message.startsWith("Cannot get pointer size, unsupported type:")) {
    // the bad type name is printed after the colon; fix it to an FFI scalar or struct
  } else throw err;
}

Prevention

When it happens

Trigger: A typo in a type name ("unit8", "int", "float", "char", "size_t"), passing a JS value instead of a type-name string, or a nested struct field using a C-style name anywhere a size must be computed.

Common situations: Hand-porting C headers and keeping C type names instead of the FFI vocabulary; generated bindings with unmapped typedefs; renames between Deno versions (older code using "usize"/"isize" variants).

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/139d8c6aa32b68e7. Report an issue: GitHub.