{"record":{"id":"705d358360cb3a00","repo":"vectordotdev/vector","slug":"event-time-path-requires-aggregateconfig-event-time","errorCode":null,"errorMessage":"event-time path requires AggregateConfig.event_time","messagePattern":"event-time path requires AggregateConfig\\.event_time","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/transforms/aggregate/event_time.rs","lineNumber":25,"sourceCode":"};\n\nuse super::AggregationMode;\nuse super::config::{EventTimeConfig, MissingTimestamp};\nuse super::transform::{Aggregate, BucketKey, MetricEntry};\nuse crate::{\n    event::{Event, EventMetadata},\n    internal_events::{\n        AggregateEventDropped, AggregateEventRecorded, AggregateFlushed, AggregateUpdateFailed,\n    },\n};\n\nimpl Aggregate {\n    /// Event-time settings; only called from the event-time path.\n    const fn event_time(&self) -> &EventTimeConfig {\n        self.config\n            .event_time\n            .as_ref()\n            .expect(\"event-time path requires AggregateConfig.event_time\")\n    }\n\n    pub(crate) fn record_event_time(\n        &mut self,\n        series: MetricSeries,\n        mut data: MetricData,\n        metadata: EventMetadata,\n        timestamp: Option<DateTime<Utc>>,\n    ) -> Option<Event> {\n        // Mirror the system-time passthrough arms before any timestamp gating.\n        if Self::passes_through_unchanged(self.config.mode, &data) {\n            return Some(Event::Metric(Metric::from_parts(series, data, metadata)));\n        }\n\n        // Mean/Stdev ignore absolute non-gauge values (no passthrough, no bucket).\n        if Self::is_silently_ignored(self.config.mode, &data) {\n            emit!(AggregateEventRecorded);\n            return None;","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/src/transforms/aggregate/event_time.rs#L7-L43","documentation":"`Aggregate::event_time()` unwraps the optional `event_time` config, asserting the caller is already on the event-time path. If `AggregateConfig.event_time` is `None` while event-time code runs, the `expect` panics. It is an internal path-invariant, not a user-facing validation error.","triggerScenarios":"Event-time functions (`record_event_time`, `is_past_bucket_cutoff`, `flush_event_time_buckets`) invoked while the transform was constructed without `event_time` in its config.","commonSituations":"A code path or fork that reaches event-time recording without gating on `config.event_time.is_some()`; tests calling these helpers directly on a default-built Aggregate.","solutions":["Set `event_time` in the aggregate transform config so the path is legitimately enabled","Gate all event-time helper calls behind a `config.event_time.is_some()` check","If building in tests, construct Aggregate with an EventTimeConfig","Report a bug if the shipped code reaches this without event_time configured"],"exampleFix":"// before\naggregate.record(data); // with event_time: None\n// after (config yaml)\ntransforms:\n  agg:\n    type: aggregate\n    event_time:\n      interval_ms: 60000","handlingStrategy":"validation","validationCode":"// only call event-time APIs when configured\nif config.event_time.is_some() {\n    aggregate.record_event_time(series, data);\n}","typeGuard":"fn is_event_time_enabled(cfg: &AggregateConfig) -> bool { cfg.event_time.is_some() }","tryCatchPattern":null,"preventionTips":["Configure `event_time` whenever relying on event-time semantics","Gate event-time call sites on `event_time.is_some()`","Add constructor assertions that path and config agree","Cover both paths in unit tests"],"tags":["rust","panic","config","transforms"],"backgroundTag":"missing-required-config-field","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"}