influxdata/influxdb · error · ValidationError

Custom partition template must have at least one part

Error message

Custom partition template must have at least one part

What it means

This error indicates a user-provided custom partition template contains zero parts. A partition template must define at least one part (e.g., a time format, tag value, or bucket) because an empty template cannot partition data. The library validates this in `PartitionTemplateBuilder`/validation code and rejects the template up front.

Solutions

  1. Add at least one part to the template before calling `build()` (e.g., `builder.add_tag_part("region")` or a time-format part)
  2. Check upstream config/inputs: if parts are built from a list, reject empty lists earlier with a clear user-facing message
  3. If the intent is no partitioning, omit the custom partition template entirely rather than passing an empty one

Example fix

// before
let template = PartitionTemplateBuilder::new().build()?; // NoParts
// after
let template = PartitionTemplateBuilder::new()
    .add_strftime_format("%Y-%m-%d")
    .build()?;
Defensive patterns

Strategy: validation

Validate before calling

fn validate_template_parts(parts: &[TemplatePart]) -> Result<(), String> {
    if parts.is_empty() {
        return Err("partition template requires at least one part".into());
    }
    Ok(())
}

Type guard

fn has_parts(t: &PartitionTemplateBuilder) -> bool {
    t.num_parts() > 0 // or inspect the parts collection
}

Try / catch

let template = builder.build().map_err(|e| match e {
    ValidationError::NoParts => anyhow!("configure at least one partition part (tag/time/bucket) before building"),
    other => anyhow!(other),
})?;

Prevention

When it happens

Trigger: Building a `PartitionTemplateBuilder` and calling `build()` (or validating a proto `PartitionTemplate`) without pushing any template parts, e.g. no `add_time_part`/`add_tag_part`/`add_bucket_part` calls, or building from an empty parts list.

Common situations: Constructing a template programmatically from dynamic config where all parts were filtered out (e.g., unset columns); parsing a user-supplied template string that yielded no parts; API/DDL requests with an empty parts array.

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/370b7095e8b4942e. Report an issue: GitHub.

Appendix: source

Thrown at core/data_types/src/partition_template.rs:203

};

use chrono::{
    DateTime, Days, Months, Utc,
    format::{self, Numeric, StrftimeItems},
};
use generated_types::influxdata::iox::partition_template::v1 as proto;
use murmur3::murmur3_32;
use percent_encoding::{AsciiSet, CONTROLS, percent_decode_str};
use schema::TIME_COLUMN_NAME;
use thiserror::Error;

use crate::{MismatchedNumPartsError, PartitionKey, PartitionKeyBuilder};

/// Reasons a user-specified partition template isn't valid.
#[derive(Debug, Error)]
pub enum ValidationError {
    /// The partition template didn't define any parts.
    #[error("Custom partition template must have at least one part")]
    NoParts,

    /// The partition template exceeded the maximum allowed number of parts.
    #[error(
        "Custom partition template specified {specified} parts. \
        Partition templates may have a maximum of {MAXIMUM_NUMBER_OF_TEMPLATE_PARTS} parts."
    )]
    TooManyParts {
        /// The number of template parts that were present in the user-provided custom partition
        /// template.
        specified: usize,
    },

    /// The partition template defines a [`TimeFormat`] part, but the
    /// provided strftime formatter is invalid.
    ///
    /// [`TimeFormat`]: [`proto::template_part::Part::TimeFormat`]
    #[error("invalid strftime format in partition template: {0}")]

View on GitHub (pinned to 06200ef96b)