vectordotdev/vector · error · syn::Error
#[derive(NamedInternalEvent)] can only be used with structs
Error message
#[derive(NamedInternalEvent)] can only be used with structs
What it means
`NamedInternalEvent` is a derive macro in vector-common-macros that implements the trait only for structs, because it derives the event name from struct fields/ident. The macro inspects `DeriveInput.data` and emits this compile error when the derive is placed on an enum or union. It is a pure compile-time diagnostic with correct span information on the offending type.
Source
Thrown at lib/vector-common-macros/src/internal_event.rs:10
use proc_macro::TokenStream;
use quote::quote;
use syn::{Data, DeriveInput, parse_macro_input, spanned::Spanned};
/// Implements `NamedInternalEvent` for structs via `#[derive(NamedInternalEvent)]`.
pub fn derive_impl_named_internal_event(item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as DeriveInput);
if !matches!(input.data, Data::Struct(_)) {
return syn::Error::new(
input.span(),
"#[derive(NamedInternalEvent)] can only be used with structs",
)
.to_compile_error()
.into();
}
let DeriveInput {
ident, generics, ..
} = input;
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
// Use a path that works from both vector-common (crate::internal_event)
// and from other crates using vector-lib (vector_lib::internal_event).
// For crates that don't depend on vector-lib but do depend on vector-common,
// we use vector_common::internal_event.
let pkg_name = std::env::var("CARGO_PKG_NAME").unwrap_or_default();
let internal_event_path = if pkg_name == "vector-common" {View on GitHub (pinned to 3708c39b12)
Solutions
- Model each internal event as its own unit/field struct and put the derive on the structs.
- If an enum grouping is desired, derive on plain structs and group them in a separate module instead.
- Check nearby usages (e.g. `rg 'NamedInternalEvent' src/`) for the accepted struct shape and copy it.
Example fix
// before
#[derive(NamedInternalEvent)]
enum SocketEvents {
Read,
Write,
}
// after
#[derive(NamedInternalEvent)]
struct SocketReadError;
#[derive(NamedInternalEvent)]
struct SocketWriteError; Defensive patterns
Strategy: validation
Validate before calling
// Compile-time by design: the error only fires on enums/unions. // CI guard: reject derives on non-structs via a lint/test that greps usage: // rg -n '#[derive(.*NamedInternalEvent.*)]' --before-context 2 | check next item is struct
Prevention
- One struct per internal event; never enums/unions.
- Copy a working derive block from an existing internal-events module when contributing.
- Read the error span — it points at the exact type declaration.
When it happens
Trigger: Writing `#[derive(NamedInternalEvent)]` on an `enum` or `union` while adding internal event instrumentation to Vector or a component crate.
Common situations: Contributors instrumenting new internal events who model them as enums (e.g. one enum with variants per severity) instead of one struct per event; copy-pasting a derive list onto a new type declaration.
Related errors
- component must have a name defined (e.g. `#[component_name("
- component cannot have multiple names defined
- {component_type}s must have a name specified (e.g. `{compone
- expected a string literal for the {component_type} name (i.e
- component name must be non-empty
AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20).
Data as JSON: /api/errors/5915613aa49824d2.
Report an issue: GitHub.