influxdata/influxdb · error
metric should be in progress
Error message
metric should be in progress
What it means
RawReporter in core/metric is an in-memory metric::Reporter: begin_metric opens an ObservationSet, report_observation appends observations to it, finish_metric closes it. report_observation expects an in-progress metric; calling it before any begin_metric (or after the set was finished) leaves in_progress as None and this expect panics.
Source
Thrown at core/metric/src/lib.rs:347
&mut self,
metric_name: &'static str,
description: &'static str,
kind: MetricKind,
) {
assert!(self.in_progress.is_none(), "metric already in progress");
self.in_progress = Some(ObservationSet {
metric_name,
description,
kind,
observations: Default::default(),
})
}
fn report_observation(&mut self, attributes: &Attributes, observation: Observation) {
let metric = self
.in_progress
.as_mut()
.expect("metric should be in progress");
metric.observations.push((attributes.clone(), observation))
}
fn finish_metric(&mut self) {
let metric = self
.in_progress
.take()
.expect("metric should be in progress");
self.completed.push(metric)
}
}
impl RawReporter {
/// Returns the observation set for a given metric name if any
pub fn metric(&self, metric_name: &str) -> Option<&ObservationSet> {
self.observations()
.iter()
.find(|observation| observation.metric_name == metric_name)View on GitHub (pinned to d28e26e048)
Solutions
- Always call begin_metric(metric_name, description, kind) before any report_observation
- Call finish_metric exactly once per begin_metric
- Encapsulate the begin/report/finish sequence in an RAII guard or helper so error paths cannot skip begin
- If you only need the collected data, read reporter.observations() instead of hand-driving the trait
Example fix
// before
reporter.report_observation(&attrs, obs); // no begin_metric -> panic
// after
reporter.begin_metric("requests", "count", MetricKind::U64Counter);
reporter.report_observation(&attrs, obs);
reporter.finish_metric();
Defensive patterns
Strategy: validation
Validate before calling
// enforce ordering with an RAII guard around the reporter
struct MetricOpen<'a>(&'a mut RawReporter);
impl<'a> MetricOpen<'a> {
fn begin(r: &'a mut RawReporter, name: &'static str, desc: &'static str, k: MetricKind) -> Self {
r.begin_metric(name, desc, k);
Self(r)
}
}
impl Drop for MetricOpen<'_> {
fn drop(&mut self) { self.0.finish_metric(); }
}
Prevention
- Always begin_metric before report_observation and finish exactly once
- Wrap the sequence in an RAII guard so error paths cannot skip begin
- Prefer the crate's built-in export paths over hand-driving the Reporter trait
When it happens
Trigger: Hand-driving the reporter out of order: report_observation before begin_metric; report_observation after finish_metric; or a wrapper that skips begin_metric on an error path but still reports.
Common situations: Writing custom exporters or test harnesses around the metric crate; refactors that reorder begin/report/finish calls; replaying buffered observations without replaying the begin call.
Related errors
- no metric in progress
- cannot fit duration into u64
- schema contains non-existent or column
- schema contains repeated column name
- can only accept once
AI-assisted analysis of influxdata/influxdb@d28e26e048 (2026-08-16).
Data as JSON: /api/errors/8c80e41f4dc59fc5.
Report an issue: GitHub.