influxdata/influxdb · critical
error reading time column
Error message
error reading time column
What it means
partition_keys calls batch.time_column().expect("error reading time column"), panicking when the batch has no time column. Partition key generation always needs timestamp data to render time-based template parts, so a batch lacking the time column is an invariant violation rather than a recoverable error.
Solutions
- Ensure the batch includes a valid 'time' column before partitioning
- Validate batch schema (time column present and of timestamp type) before calling partition_keys
- If building batches manually, always append the time column returned by the write API
Example fix
// before let keys: Vec<_> = partition_keys(&batch, template.parts()).collect(); // after assert!(batch.time_column().is_some(), "batch must contain a time column before partitioning"); let keys: Vec<_> = partition_keys(&batch, template.parts()).collect();
Defensive patterns
Strategy: validation
Validate before calling
if batch.time_column().is_none() {
return Err(anyhow!("batch is missing the required 'time' column; cannot compute partition keys"));
} Type guard
fn has_time_column(b: &dyn Batch) -> bool { b.time_column().is_some() } Prevention
- Always include the time column when constructing record batches for the write path
- Validate batch schemas on ingest before buffering
- Never drop or rename the 'time' column in upstream transforms
When it happens
Trigger: Calling partition_keys/partition_batch on a Batch whose time_column() returns None — i.e. a record batch without a 'time' column or with an unreadable/invalid time column.
Common situations: Feeding a hand-built Arrow RecordBatch into partitioning without a time column; a write path that dropped or renamed the time column upstream; corrupted parquet data missing the time column.
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
- table batch must contain time column
- column id in series key should be valid
- duration not to overflow
- Existing transaction for table should not exist
- expected bucket id, got string
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/fce84db081ee4dfe.
Report an issue: GitHub.
Appendix: source
Thrown at core/partition/src/lib.rs:83
}
range_encode(partition_keys(batch, template.parts()))
}
/// Returns an iterator of partition keys for the given table batch.
///
/// This function performs deduplication on returned keys; the returned iterator
/// yields [`Some`] containing the partition key string when a new key is
/// generated, and [`None`] when the generated key would equal the last key.
pub fn partition_keys<'a, T>(
batch: &'a T,
template_parts: impl Iterator<Item = TemplatePart<'a>>,
) -> impl Iterator<Item = Option<Result<String, PartitionKeyError>>> + 'a
where
T: Batch,
{
// Extract the timestamp data.
let time = batch.time_column().expect("error reading time column");
// Convert TemplatePart into an ordered array of Template
let mut template = template_parts
.map(|v| Template::from((v, batch, time)))
.collect::<Vec<_>>();
// Track the length of the last yielded partition key, and pre-allocate the
// next partition key string to match it.
//
// In the happy path, keys of consistent sizes are generated and the
// allocations reach a minimum. If the keys are inconsistent, at best a
// subset of allocations are eliminated, and at worst, a few bytes of memory
// is temporarily allocated until the resulting string is shrunk down.
let mut last_len = 5;
// The first row in a batch must always be evaluated to produce a key.
//
// Row 0 is guaranteed to exist, otherwise attempting to read the timeView on GitHub (pinned to 06200ef96b)