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
- Guard the call site: return early or skip reorganization when split_times is empty.
- Compute split_times from actual chunk time ranges so at least one boundary exists.
- If empty splits are legitimately expected, use the builder API directly instead of split_plan.
- 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
- Never call split_plan with an empty Vec — check len() > 0 first.
- Derive split_times from actual chunk time ranges.
- Wrap split_plan in a helper that validates inputs and returns Result.
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
- split_times[ ]: must be smaller than split_times[ ]
- By the point that we're doing partitioning, we should've…
- Existing transaction for table should not exist
- Key column, , of current batch has no data
- Key column, , of last_batch has no data
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_builderView on GitHub (pinned to 06200ef96b)