influxdata/influxdb · error

Split plan does not accept empty split_times

Error message

Split plan does not accept empty split_times

What it means

In QueryDatabase::split_plan (core/iox_query/src/frontend/reorg.rs), the split_times argument must contain at least one timestamp because each entry defines a split boundary for reorganization. An empty Vec yields zero split expressions, which is meaningless, so the function panics deliberately as an internal invariant check.

Solutions

  1. Guard the call site: return early or skip reorganization when split_times is empty.
  2. Compute split_times from actual chunk time ranges so at least one boundary exists.
  3. If empty splits are legitimately expected, use the builder API directly instead of split_plan.
  4. Replace the panic with Result-returning validation if you maintain a fork.

Example fix

// before
let plan = db.split_plan(&table, &schema, chunks, &[])?;
// after
if split_times.is_empty() {
    return Ok(None); // nothing to split
}
let plan = db.split_plan(&table, &schema, chunks, &split_times)?;
Defensive patterns

Strategy: validation

Validate before calling

if split_times.is_empty() {
    // skip reorg entirely; there are no boundaries to split on
    return Ok(None);
}

Try / catch

// split_plan panics (not Result); guard before calling
assert!(!split_times.is_empty(), "split_times must not be empty");
let plan = split_plan(...);

Prevention

When it happens

Trigger: Calling split_plan with an empty iterator/Vec for split_times while supplying chunks to reorganize.

Common situations: Reorg tooling computing split times from statistics that were empty; users calling split_plan directly with a default/empty Vec; upstream filtering that removed all candidate boundaries.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at core/iox_query/src/frontend/reorg.rs:185

    ///  X | time
    /// ---+-----
    ///  c | 4000
    /// ```
    pub fn split_plan<I>(
        &self,
        table_id: TableId,
        table_name: Arc<str>,
        schema: &Schema,
        chunks: I,
        output_sort_key: SortKey,
        split_times: Vec<i64>,
    ) -> Result<LogicalPlan>
    where
        I: IntoIterator<Item = Arc<dyn QueryChunk>>,
    {
        // split_times must have values
        if split_times.is_empty() {
            panic!("Split plan does not accept empty split_times");
        }

        let mut builder = ProviderBuilder::new(Arc::clone(&table_name), schema.clone())
            .with_enable_deduplication(true);

        for chunk in chunks {
            builder = builder.add_chunk(chunk);
        }

        let provider = builder.build().context(CreatingScanSnafu {
            table_name: table_name.as_ref(),
            table_id,
        })?;
        let plan_builder = Arc::new(provider)
            .into_logical_plan_builder()
            .context(BuildingPlanSnafu)?;
        let sort_expr = logical_sort_key_exprs(&output_sort_key);
        let plan = plan_builder

View on GitHub (pinned to 06200ef96b)