{"record":{"id":"5915613aa49824d2","repo":"vectordotdev/vector","slug":"derive-namedinternalevent-can-only-be-used-wit","errorCode":null,"errorMessage":"#[derive(NamedInternalEvent)] can only be used with structs","messagePattern":"#\\[derive\\(NamedInternalEvent\\)\\] can only be used with structs","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"lib/vector-common-macros/src/internal_event.rs","lineNumber":10,"sourceCode":"use proc_macro::TokenStream;\nuse quote::quote;\nuse syn::{Data, DeriveInput, parse_macro_input, spanned::Spanned};\n\n/// Implements `NamedInternalEvent` for structs via `#[derive(NamedInternalEvent)]`.\npub fn derive_impl_named_internal_event(item: TokenStream) -> TokenStream {\n    let input = parse_macro_input!(item as DeriveInput);\n\n    if !matches!(input.data, Data::Struct(_)) {\n        return syn::Error::new(\n            input.span(),\n            \"#[derive(NamedInternalEvent)] can only be used with structs\",\n        )\n        .to_compile_error()\n        .into();\n    }\n\n    let DeriveInput {\n        ident, generics, ..\n    } = input;\n    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();\n\n    // Use a path that works from both vector-common (crate::internal_event)\n    // and from other crates using vector-lib (vector_lib::internal_event).\n    // For crates that don't depend on vector-lib but do depend on vector-common,\n    // we use vector_common::internal_event.\n    let pkg_name = std::env::var(\"CARGO_PKG_NAME\").unwrap_or_default();\n    let internal_event_path = if pkg_name == \"vector-common\" {","sourceCodeStart":1,"sourceCodeEnd":28,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/lib/vector-common-macros/src/internal_event.rs#L1-L28","documentation":"This is a compile-time diagnostic from the `NamedInternalEvent` derive macro in vector-common-macros. The macro generates an implementation of the `NamedInternalEvent` trait, which requires a named struct's fields to build the event name. Applying the derive to an enum, union, or unit struct is rejected because the macro's codegen only knows how to handle struct-shaped input (`Data::Struct`).","triggerScenarios":"Attaching `#[derive(NamedInternalEvent)]` to an `enum`, a `union`, or any non-struct item, then running `cargo build`/`cargo check`. The proc macro's `derive_impl_named_internal_event` parses the item as `DeriveInput` and matches `input.data`; any variant other than `Data::Struct(_)` returns `syn::Error` at the item's span.","commonSituations":"Refactoring a struct into an enum while leaving the derive attribute in place; copy-pasting the derive onto an enum of event variants; assuming the trait supports sum types like other event traits.","solutions":["Move `#[derive(NamedInternalEvent)]` to a struct instead of the enum/union","If you need an enum of events, wrap the derive on each struct variant's payload type or implement `NamedInternalEvent` manually for the enum","If the item was converted from a struct to an enum, remove the derive and hand-write the trait impl"],"exampleFix":"// before\n#[derive(NamedInternalEvent)]\nenum EventKind { A, B }\n// after\n#[derive(NamedInternalEvent)]\nstruct EventKind { name: &'static str }","handlingStrategy":"validation","validationCode":"fn assert_named_internal_event_target<T>() { let _ = std::marker::PhantomData::<T>; }\n// Only attach the derive to `struct` items; enums/unions must impl the trait manually.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run cargo check immediately after adding a derive so macro errors surface on the right item","Never attach event derives to enums; implement the trait by hand for sum types"],"tags":["rust","proc-macro","derive-macro"],"backgroundTag":"unsupported-operation","analyzedSha":"bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013","analyzedAt":"2026-09-16T02:53:35.741Z","contentChangedAt":"2026-09-16T02:53:35.741Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}