influxdata/influxdb · error · MismatchedNumPartsError

Expected parts in key due to template passed in, found …

Error message

Expected {expected} parts in key due to template passed in, found {found}. (Note: this may be due to a provided `part` containing the delimiter, `|`, resulting in the key containing more parts than necessary)

What it means

MismatchedNumPartsError is returned from NamespacePartitionTemplateOverride::part_key() when the number of part values supplied does not match the number of parts declared by the template. expected is the template's part count and found is the number of values passed in. The library throws it because the key can only be built when every templated part receives exactly one value.

Solutions

  1. Compare the expected/found numbers in the message with your partition template definition and pass exactly that many values.
  2. Check each part value for the '|' delimiter and escape, reject, or re-map values containing it.
  3. Re-read the table's current partition template after any ALTER TABLE change and update your writer accordingly.
  4. Compute the part count from the template at runtime instead of hardcoding it.

Example fix

// before
let key = tmpl.part_key(&[region])?; // template has 2 parts
// after
let key = tmpl.part_key(&[region, day])?; // one value per template part
Defensive patterns

Strategy: validation

Validate before calling

let expected = tmpl.num_parts(); // part count from the template
let found = parts.len();
if found != expected || parts.iter().any(|p| p.contains('|')) {
    return Err("part values must match template count and contain no '|'".into());
}

Try / catch

match tmpl.part_key(&parts) {
    Ok(key) => use(key),
    Err(MismatchedNumPartsError { expected, found }) => {
        log::error!("template needs {expected} parts, got {found}; refresh template definition");
        reload_template_and_retry()
    }
}

Prevention

When it happens

Trigger: Calling part_key() with fewer or more values than the partition template declares, e.g. a template with 2 parts but only 1 value passed, or a single part value that itself contains the '|' delimiter causing extra parts to appear.

Common situations: Changing a table's partition template (adding a tag/part column) while writers still send the old number of values; tag values that literally contain '|' producing more split parts than expected; schema drift between producer and template configuration.

Related errors


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

Appendix: source

Thrown at core/data_types/src/partition.rs:243

        <String as sqlx::Encode<sqlx::Sqlite>>::encode(self.0.to_string(), buf)
    }
}

impl sqlx::Decode<'_, sqlx::Sqlite> for PartitionKey {
    fn decode(
        value: <sqlx::Sqlite as sqlx::database::Database>::ValueRef<'_>,
    ) -> Result<Self, Box<dyn std::error::Error + 'static + Send + Sync>> {
        Ok(Self(
            <String as sqlx::Decode<sqlx::Sqlite>>::decode(value)?.into(),
        ))
    }
}

/// An error struct that could be returned from [`NamespacePartitionTemplateOverride::part_key()`]
/// if validation fails. [`Self::expected`] will be equal to the number of parts which the template had,
/// and [`Self::found`] will be equal to the number of fields passed in as the argument `parts`
#[derive(Debug, Copy, Clone, Error)]
#[error(
    "Expected {expected} parts in key due to template passed in, found {found}. (Note: this may be due to a provided `part` containing the delimiter, `|`, resulting in the key containing more parts than necessary)"
)]
pub struct MismatchedNumPartsError {
    /// The number of parts that the tmpl passed into [`NamespacePartitionTemplateOverride::part_key()`] had
    pub expected: usize,
    /// The number of parts that were passed into [`NamespacePartitionTemplateOverride::part_key()`]
    pub found: usize,
}

/// A utility struct to create a [`PartitionKey`] for a specific
/// [`NamespacePartitionTemplateOverride`] and verify that this key has the correct amount of
/// `parts` in it to be used with the provided template.
#[derive(Debug)]
pub struct PartitionKeyBuilder {
    /// The incremental string that is built as [`Self::push()`] is called multiple times, and what
    /// will be turned into the [`PartitionKey`] if validation succeeds.
    key: String,
    /// The number of expected `parts` that this key should have, based on the template provided in

View on GitHub (pinned to 06200ef96b)