denoland/deno · error · syn::Error

Unions are not supported

Error message

Unions are not supported

What it means

#[derive(FromV8)] dispatches on the input item's Data: structs and enums get generated FromV8 impls, but Data::Union is explicitly rejected with this error on the item's span. Rust unions have no representation that can be safely or meaningfully converted from a V8 value, so the derive refuses rather than generating unsound code.

Source

Thrown at libs/ops/conversion/from_v8/mod.rs:29

use syn::DeriveInput;
use syn::Error;
use syn::parse2;
use syn::spanned::Spanned;

pub fn from_v8(item: TokenStream) -> Result<TokenStream, Error> {
  let input = parse2::<DeriveInput>(item)?;
  let span = input.span();
  let ident = input.ident;
  let ident_string = ident.to_string();

  let out = match input.data {
    Data::Struct(data) => {
      create_impl(ident, r#struct::get_body(ident_string, span, data)?)
    }
    Data::Enum(data) => {
      create_impl(ident, r#enum::get_body(ident_string, input.attrs, data)?)
    }
    Data::Union(_) => return Err(Error::new(span, "Unions are not supported")),
  };

  Ok(out)
}

fn convert_or_serde(
  serde: bool,
  span: proc_macro2::Span,
  value: TokenStream,
) -> TokenStream {
  if serde {
    quote_spanned! { span =>
      ::deno_core::serde_v8::from_v8(
        __scope,
        #value,
      ).map_err(::deno_error::JsErrorBox::from_err)?
    }
  } else {

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Replace the union with a struct or enum that expresses the same alternatives (enums model 'one of' safely).
  2. If you need raw reinterpretation, keep the union out of V8 boundaries and convert manually inside a hand-written op.

Example fix

// before
#[derive(FromV8)]
union Raw {
  a: u32,
  b: f32,
} // error: Unions are not supported

// after
#[derive(FromV8)]
enum Raw {
  A(u32),
  B(f32),
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Annotating a union declaration with #[derive(FromV8)], e.g. union Raw { a: u32, b: f32 } used as an op parameter or return type.

Common situations: Reusing a FFI/interop union type in an op signature and deriving the conversion traits wholesale via a shared prelude; copy-pasting a derive list from a struct onto a union.

Related errors


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