influxdata/influxdb · error

Expected three arguments

Error message

Expected three arguments

What it means

This panic lives in a test-local mock ScalarUDF's `invoke_with_args` used to validate argument shapes during gapfill tests. It uses a let-else pattern: if the args slice is not exactly `[_, source, origin]` (three arguments), it panics with "Expected three arguments". It signals that the mock UDF was invoked with the wrong arity, or the mock itself was wired up incorrectly.

Solutions

  1. Check the call site constructing the mock UDF call and ensure exactly three arguments are passed (stride/source placeholders).
  2. Inspect args.args.len() at the panic to see what was actually delivered.
  3. If a DataFusion upgrade changed argument plumbing, update the mock's let-else pattern accordingly.

Example fix

// before
let [_, source, origin] = args.args.as_slice() else {
    panic!("Expected three arguments");
};
// after
let [_, source, origin] = args.args.as_slice() else {
    panic!("expected three arguments, got {}: {:?}", args.args.len(), args.args);
};
Defensive patterns

Strategy: validation

Validate before calling

assert_eq!(args.args.len(), 3, "mock UDF requires exactly 3 args, got {}", args.args.len());

Type guard

fn split3(args: &[ColumnarValue]) -> Option<(&ColumnarValue, &ColumnarValue, &ColumnarValue)> {
    match args { [a, b, c] => Some((a, b, c)), _ => None }
}

Try / catch

let [_, source, origin] = args.args.as_slice() else {
    panic!("expected three arguments, got {}: {:?}", args.args.len(), args.args);
};

Prevention

When it happens

Trigger: The mock UDF registered in the test is called with fewer or more than 3 arguments — e.g. the test builds the Expr with a wrong number of children, or args.args contains extra values.

Common situations: Developers changing the function signature (adding/removing args in tests), or DataFusion version changes altering how ScalarFunctionArgs.args is populated, trigger this while running gapfill tests.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at core/query_functions/src/date_bin_wallclock.rs:927

        fn as_any(&self) -> &dyn std::any::Any {
            self
        }

        fn name(&self) -> &'static str {
            "test_date_bin_udf"
        }

        fn signature(&self) -> &Signature {
            &self.signature
        }

        fn return_type(&self, arg_types: &[DataType]) -> Result<DataType> {
            Ok(arg_types[1].clone())
        }

        fn invoke_with_args(&self, args: ScalarFunctionArgs) -> Result<ColumnarValue> {
            let [_, source, origin] = args.args.as_slice() else {
                panic!("Expected three arguments");
            };
            assert_eq!(source.data_type(), origin.data_type());
            let DataType::Timestamp(_, tz) = source.data_type() else {
                panic!("Expected timestamp data type");
            };
            assert!(tz.is_some());
            Ok(source.clone())
        }
    }

    fn arg_to_fields(args: &[ColumnarValue]) -> Vec<FieldRef> {
        args.iter()
            .enumerate()
            .map(|(idx, val)| Arc::new(Field::new(format!("arg_{idx}"), val.data_type(), false)))
            .collect()
    }

    fn return_field(dt: DataType) -> FieldRef {

View on GitHub (pinned to 06200ef96b)