{"record":{"id":"06b188c64bfa2656","repo":"denoland/deno","slug":"unions-are-not-supported","errorCode":null,"errorMessage":"Unions are not supported","messagePattern":"Unions are not supported","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"libs/ops/conversion/from_v8/mod.rs","lineNumber":29,"sourceCode":"use syn::DeriveInput;\nuse syn::Error;\nuse syn::parse2;\nuse syn::spanned::Spanned;\n\npub fn from_v8(item: TokenStream) -> Result<TokenStream, Error> {\n  let input = parse2::<DeriveInput>(item)?;\n  let span = input.span();\n  let ident = input.ident;\n  let ident_string = ident.to_string();\n\n  let out = match input.data {\n    Data::Struct(data) => {\n      create_impl(ident, r#struct::get_body(ident_string, span, data)?)\n    }\n    Data::Enum(data) => {\n      create_impl(ident, r#enum::get_body(ident_string, input.attrs, data)?)\n    }\n    Data::Union(_) => return Err(Error::new(span, \"Unions are not supported\")),\n  };\n\n  Ok(out)\n}\n\nfn convert_or_serde(\n  serde: bool,\n  span: proc_macro2::Span,\n  value: TokenStream,\n) -> TokenStream {\n  if serde {\n    quote_spanned! { span =>\n      ::deno_core::serde_v8::from_v8(\n        __scope,\n        #value,\n      ).map_err(::deno_error::JsErrorBox::from_err)?\n    }\n  } else {","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/libs/ops/conversion/from_v8/mod.rs#L11-L47","documentation":"#[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.","triggerScenarios":"Annotating a union declaration with #[derive(FromV8)], e.g. union Raw { a: u32, b: f32 } used as an op parameter or return type.","commonSituations":"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.","solutions":["Replace the union with a struct or enum that expresses the same alternatives (enums model 'one of' safely).","If you need raw reinterpretation, keep the union out of V8 boundaries and convert manually inside a hand-written op."],"exampleFix":"// before\n#[derive(FromV8)]\nunion Raw {\n  a: u32,\n  b: f32,\n} // error: Unions are not supported\n\n// after\n#[derive(FromV8)]\nenum Raw {\n  A(u32),\n  B(f32),\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never apply conversion derives (FromV8/ToV8) to unions; represent 'one of several layouts' with an enum instead.","If your crate uses a shared derive prelude, exclude unions explicitly rather than applying derives wholesale."],"tags":["proc-macro","derive","from-v8","union","compile-time","deno-core"],"backgroundTag":"derive-macro-unsupported-shape","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}