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

  1. Model each internal event as its own unit/field struct and put the derive on the structs.
  2. If an enum grouping is desired, derive on plain structs and group them in a separate module instead.
  3. 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

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


AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20). Data as JSON: /api/errors/5915613aa49824d2. Report an issue: GitHub.