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

  1. Always call begin_metric(metric_name, description, kind) before any report_observation
  2. Call finish_metric exactly once per begin_metric
  3. Encapsulate the begin/report/finish sequence in an RAII guard or helper so error paths cannot skip begin
  4. 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

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


AI-assisted analysis of influxdata/influxdb@d28e26e048 (2026-08-16). Data as JSON: /api/errors/8c80e41f4dc59fc5. Report an issue: GitHub.