nautechsystems/nautilus_trader · error
Failed to insert into bar table: {e}
Error message
Failed to insert into bar table: {e} What it means
add_bar wraps any sqlx error that occurs while binding/inserting a Bar row into the `bar` table inside anyhow::anyhow!, losing the concrete error type. It means the INSERT into the bar table failed at the database layer — typically a schema mismatch, constraint violation, or connection issue. The library throws it so callers get a single anyhow::Result with a descriptive message and the underlying sqlx error chained as source.
Source
Thrown at crates/infrastructure/src/sql/queries.rs:1379
instrument_id = $1, step = $2, bar_aggregation = $3::bar_aggregation, price_type = $4::price_type, aggregation_source = $5::aggregation_source,
open = $6, high = $7, low = $8, close = $9, volume = $10, ts_event = $11, ts_init = $12, updated_at = CURRENT_TIMESTAMP
"#)
.bind(bar.bar_type.instrument_id().to_string())
.bind(bar_step)
.bind(BarAggregationPg(bar.bar_type.spec().aggregation))
.bind(PriceTypePg(bar.bar_type.spec().price_type))
.bind(AggregationSourcePg(bar.bar_type.aggregation_source()))
.bind(bar.open.to_string())
.bind(bar.high.to_string())
.bind(bar.low.to_string())
.bind(bar.close.to_string())
.bind(bar.volume.to_string())
.bind(bar.ts_event.to_string())
.bind(bar.ts_init.to_string())
.execute(pool)
.await
.map(|_| ())
.map_err(|e| anyhow::anyhow!("Failed to insert into bar table: {e}"))
}
/// Loads all `Bar` entries for `instrument_id` via the provided `pool`.
///
/// # Errors
///
/// Returns an error if the SQL SELECT or deserialization fails.
pub async fn load_bars(
pool: &PgPool,
instrument_id: &InstrumentId,
) -> anyhow::Result<Vec<Bar>> {
sqlx::query_as::<_, BarRow>(
r#"SELECT * FROM "bar" WHERE instrument_id = $1 ORDER BY ts_event ASC"#,
)
.bind(instrument_id.to_string())
.fetch_all(pool)
.await
.map(|rows| rows.into_iter().map(|row| row.0).collect())View on GitHub (pinned to 18893faf8b)
Solutions
- Log/print the chained source (`e.source()`) or `{:?}` of the anyhow error to see the underlying sqlx message.
- Verify the `bar` table exists and matches the current schema by running the crate's migration/initialization (e.g. `create_bar_tables`) before inserting.
- Check DB connectivity and that the PgPool/SqlitePool is alive and credentials are valid.
- Ensure you are not inserting a duplicate bar for the same instrument_id/ts_event if a uniqueness constraint applies.
- Confirm column types can hold the stringified values (volume, ts_event, ts_init).
Example fix
// before let pool = PgPool::connect_lazy(url)?; queries::postgres::add_bar(&pool, &bar).await?; // after let pool = PgPool::connect(url).await?; // fail fast on bad connection sqlx::migrate!().run(&pool).await?; // ensure schema exists queries::postgres::add_bar(&pool, &bar).await?;
Defensive patterns
Strategy: validation
Validate before calling
// Rust
async fn bar_table_ready(pool: &sqlx::PgPool) -> anyhow::Result<()> {
sqlx::query(r#"SELECT 1 FROM \"bar\" LIMIT 1"#).fetch_optional(pool).await
.map(|_| ())
.map_err(|e| anyhow::anyhow!("bar table not initialized: {e}"))
} Try / catch
// Rust
match queries::postgres::add_bar(&pool, &bar).await {
Ok(()) => (),
Err(e) => {
tracing::error!(source = ?std::error::Error::source(&e), "bar insert failed");
return Err(e);
}
} Prevention
- Run schema creation/migrations at startup before any writes
- Fail fast by connecting (not connect_lazy) so bad credentials surface early
- Log the anyhow error source chain to expose the raw sqlx cause
- Avoid duplicate bars per instrument_id/ts_event in your ingestion pipeline
When it happens
Trigger: Calling add_bar when the `bar` table does not exist or was created with an older schema, when bar fields exceed column types/precision (e.g. oversized instrument_id or volume), when the connection pool is dead, or when a UNIQUE/PRIMARY KEY constraint (instrument_id + ts_event) is violated.
Common situations: Running against a Postgres/SQLite database migrated with an outdated schema version; switching between SQLite and Postgres backends with incompatible types; network drop between pool creation and execute; inserting a duplicate bar for the same instrument/timestamp.
Related errors
- Failed to persist execution client {client_id}: {e}
- Failed to insert into order_position_index table: {e}
- Failed to insert instrument close: {e}
- Failed to load bars: {e}
- Failed to validate order client origin: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/af5796f4797a4330.
Report an issue: GitHub.