influxdata/influxdb · error

should be registered

Error message

should be registered

What it means

A test helper in gapfill.rs looks up the DATE_BIN_GAPFILL UDF by name in the function registry via `crate::registry().udf(super::DATE_BIN_GAPFILL_UDF_NAME).expect("should be registered")`. The panic means the date_bin_gapfill UDF was not found in the registry when the helper built its expression — i.e. the UDF was never registered or its name constant changed.

Solutions

  1. Check that `crate::registry()` registers all gapfill UDFs (date_bin_gapfill, locf, interpolate) unconditionally or for the test cfg.
  2. Verify DATE_BIN_GAPFILL_UDF_NAME matches the name passed to registry.register_udf.
  3. Reproduce with `cargo test -p query_functions gapfill` and print the registry's UDF names if unsure.

Example fix

// before
fn date_bin_gapfill(stride: Expr, source: Expr, origin: Expr) -> Expr {
    crate::registry().udf(super::DATE_BIN_GAPFILL_UDF_NAME).expect("should be registered")...
}
// after (ensure registration first, e.g. in test setup)
let funcs = crate::all_default_functions();
assert!(funcs.iter().any(|f| f.name() == super::DATE_BIN_GAPFILL_UDF_NAME), "date_bin_gapfill not registered");
Defensive patterns

Strategy: validation

Validate before calling

let udf = crate::registry().udf(super::DATE_BIN_GAPFILL_UDF_NAME)
    .unwrap_or_else(|| panic!("{} should be registered", super::DATE_BIN_GAPFILL_UDF_NAME));

Type guard

fn registered(reg: &dyn FunctionRegistry, name: &str) -> bool {
    reg.udf(name).is_ok()
}

Try / catch

match crate::registry().udf(super::DATE_BIN_GAPFILL_UDF_NAME) {
    Ok(udf) => udf.call(vec![stride, source, origin]),
    Err(e) => panic!("date_bin_gapfill should be registered: {e}"),
}

Prevention

When it happens

Trigger: Calling the `date_bin_gapfill(stride, source, origin)` test helper before/without registering the gapfill UDFs, or after renaming DATE_BIN_GAPFILL_UDF_NAME so registry lookup returns None.

Common situations: Developers removing the UDF registration (e.g. during a refactor or feature-gating with cfg attributes), renaming the UDF constant, or constructing the registry without gapfill functions hit this in tests.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19). Data as JSON: /api/errors/8091d137ed7da000. Report an issue: GitHub.

Appendix: source

Thrown at core/query_functions/src/gapfill.rs:413

    }))
});

#[cfg(test)]
mod test {
    use arrow::array::{ArrayRef, Float64Array, TimestampNanosecondArray};
    use arrow::record_batch::RecordBatch;
    use datafusion::common::assert_contains;
    use datafusion::error::Result;
    use datafusion::prelude::{Expr, SessionContext, col};
    use datafusion::scalar::ScalarValue;
    use datafusion_util::lit_timestamptz_nano;
    use schema::TIME_DATA_TIMEZONE;
    use std::sync::Arc;

    fn date_bin_gapfill(stride: Expr, source: Expr, origin: Expr) -> Expr {
        crate::registry()
            .udf(super::DATE_BIN_GAPFILL_UDF_NAME)
            .expect("should be registered")
            .call(vec![stride, source, origin])
    }

    fn lit_interval_milliseconds(v: i64) -> Expr {
        Expr::Literal(ScalarValue::new_interval_mdn(0, 0, v * 1_000_000), None)
    }

    #[tokio::test]
    async fn date_bin_gapfill_errs() -> Result<()> {
        let times = Arc::new(
            TimestampNanosecondArray::from(vec![Some(1000)])
                .with_timezone_opt(TIME_DATA_TIMEZONE()),
        );
        let rb = RecordBatch::try_from_iter(vec![("time", times as ArrayRef)])?;
        let ctx = SessionContext::new();
        ctx.register_batch("t", rb).unwrap();

        let df = ctx.table("t").await?.select(vec![date_bin_gapfill(

View on GitHub (pinned to 06200ef96b)