{"record":{"id":"8c9c3fdb67172b45","repo":"denoland/deno","slug":"unit-fields-are-currently-not-supported","errorCode":null,"errorMessage":"Unit fields are currently not supported","messagePattern":"Unit fields are currently not supported","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"libs/ops/conversion/from_v8/struct.rs","lineNumber":141,"sourceCode":"                let __element_value = __array.get_index(__scope, #i).ok_or_else(|| ::deno_error::JsErrorBox::type_error(concat!(\"Missing element \", #i, \" on '\", #ident_string, \"'\")))?;\n                #converter\n              }\n            }\n          })\n          .collect::<Vec<_>>();\n\n        quote! {\n          let __array = ::deno_core::v8::Local::<::deno_core::v8::Array>::try_from(__value)\n            .map_err(|err| ::deno_error::JsErrorBox::from_err(::deno_core::error::DataError::from(err)))?;\n\n          Ok(Self(#(#fields),*))\n        }\n      };\n\n      Ok(value)\n    }\n    Fields::Unit => {\n      Err(Error::new(span, \"Unit fields are currently not supported\"))\n    }\n  }\n}\n\nstruct StructField {\n  name: Ident,\n  js_name: Ident,\n  default_value: Option<Expr>,\n  serde: bool,\n  ty: Type,\n}\n\nimpl TryFrom<Field> for StructField {\n  type Error = Error;\n  fn try_from(value: Field) -> Result<Self, Self::Error> {\n    let span = value.span();\n    let mut default_value: Option<Expr> = None;\n    let crate::conversion::SharedAttribute {","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/libs/ops/conversion/from_v8/struct.rs#L123-L159","documentation":"#[derive(FromV8)] on a struct matches on Fields; named and unnamed (tuple) fields are converted from V8 objects/arrays, but Fields::Unit — a fieldless unit struct like struct Marker; — is rejected. There is no V8 value shape the derive maps a unit struct to, so it fails at compile time instead of generating a stub.","triggerScenarios":"Deriving FromV8 on a unit struct: #[derive(FromV8)] struct Empty; (also struct Empty {} is a named-fields struct with zero fields — the truly rejected form is the unit struct with no braces).","commonSituations":"Marker/phantom types accidentally swept into an op module's derive list; refactoring a struct down to zero fields and leaving the derive on; generating derives via a macro that applies them uniformly.","solutions":["Give the type a real payload, e.g. turn it into a newtype struct Empty(()) or add a field, so the derive has something to convert.","Remove the FromV8 derive — a unit type never crosses the V8 boundary as data; pass nothing (or a plain op with no args) instead.","If it must appear in signatures, write a manual FromV8 impl that accepts any value and ignores it."],"exampleFix":"// before\n#[derive(FromV8)]\nstruct Marker; // error: Unit fields are currently not supported\n\n// after\n#[derive(FromV8)]\nstruct Marker(Option<serde_json::Value>); // or drop the derive entirely","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Audit derives after refactoring a struct to zero fields — unit types cannot cross the V8 boundary via these derives.","Keep marker/phantom types out of op signatures entirely instead of deriving conversions for them."],"tags":["proc-macro","derive","from-v8","unit-struct","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"}