influxdata/influxdb · error
table should exist by id
Error message
table should exist by id
What it means
table_tx_or_create creates (or looks up) a table and then expects the resulting id to be present in self.tables. Since table_or_create is expected to have inserted a TableTransaction for that id, get_mut_by_id returning None means the insert path skipped the transaction (e.g. the table already existed and the else branch returned None upstream of a broken assumption) or the map was mutated inconsistently.
Solutions
- Prefer obtaining the transaction from the same call: use table_tx_or_create rather than mixing table_or_create with separate map lookups
- Ensure every path that returns a table_id also inserts a TableTransaction keyed by that id in the same batch
- Check the library version for a fix to the existing-table branch of table_or_create and upgrade
- If reproducible on the latest version, file a bug with the failing call sequence
Example fix
// before
let id = batch.table_or_create("cpu")?;
let tx = batch.get_mut_by_id(&id).expect("table should exist by id");
// after
let tx = batch.table_tx_or_create("cpu")?; // single source of truth Defensive patterns
Strategy: validation
Validate before calling
// confirm the table exists in the schema before requesting a transaction
if db_schema.table_id(table_name).is_none() && !batch.will_create_table(table_name) {
return Err(anyhow!("table {} unknown and not scheduled for creation", table_name));
} Type guard
fn tx_for<'a>(batch: &'a mut CatalogBatch, id: &TableId) -> Option<&'a mut TableTransaction> {
batch.tables.get_mut_by_id(id)
} Try / catch
let Some(tx) = batch.tables.get_mut_by_id(&id) else {
return Err(anyhow!("no table transaction for id {id:?}; create it first"));
}; Prevention
- Use table_tx_or_create instead of separate lookup+expect
- Ensure every table_id returned also has a transaction inserted in the same batch
- Add debug_assert!s when building batches to catch missing transactions early
- Stay on a library version where the existing-table path inserts a transaction
When it happens
Trigger: Calling table_tx_or_create when table_or_create returned an existing table's id without inserting a TableTransaction for it into self.tables, so the subsequent get_mut_by_id finds nothing.
Common situations: Write paths that touch an already-existing table but expect an open table transaction; batches built through mixed legacy/new APIs where the existing table was never registered as a transaction.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- column id in series key should be valid
- Existing transaction for table should not exist
- no duplicate table by ID or name
- ordered catalog batch should succeed when applied
- auto field family exists
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/7b42f56779d306c0.
Report an issue: GitHub.
Appendix: source
Thrown at influxdb3_catalog/src/catalog/versions/v2/update.rs:1922
pub fn table_or_create(&mut self, table_name: &str) -> Result<TableId> {
match self.table_transaction(table_name) {
Some(tx) => Ok(tx.table.table_id),
None => self.create_table(
table_name,
create_table_columns::none(),
None,
FieldFamilyMode::Aware,
),
}
}
pub fn table_tx_or_create(&mut self, table_name: &str) -> Result<&mut TableTransaction> {
let id = self.table_or_create(table_name)?;
Ok(self
.tables
.get_mut_by_id(&id)
.expect("table should exist by id"))
}
pub fn column_or_create(
&mut self,
table_name: &str,
column_name: &str,
column_type: InfluxColumnType,
) -> Result<ColumnDefinition> {
let Some(table_tx) = self.table_transaction(table_name) else {
return Err(CatalogError::NotFound(table_name.to_string()));
};
match table_tx.table.column_definition(column_name) {
Some(def) if def.column_type() == column_type => Ok(def),
Some(def) => Err(CatalogError::InvalidColumnType {
column_name: Arc::clone(&def.name()),
expected: def.column_type(),
got: column_type,
}),View on GitHub (pinned to 06200ef96b)