nautechsystems/nautilus_trader · error
Failed to load general table: {e}
Error message
Failed to load general table: {e} What it means
`DatabaseQueries::load` runs `SELECT * FROM general` and decodes every row into an `AHashMap<String, Vec<u8>>`, wrapping any sqlx failure in this anyhow error. Failure means the query or row decoding failed: connectivity loss, missing table, or schema/data drift where stored values no longer match the expected row types.
Source
Thrown at crates/infrastructure/src/sql/queries.rs:95
}
/// Loads all entries from the `general` table via the provided `pool`.
///
/// # Errors
///
/// Returns an error if the SELECT operation fails.
pub async fn load(pool: &PgPool) -> anyhow::Result<AHashMap<String, Vec<u8>>> {
sqlx::query_as::<_, GeneralRow>("SELECT * FROM general")
.fetch_all(pool)
.await
.map(|rows| {
let mut cache: AHashMap<String, Vec<u8>> = AHashMap::new();
for row in rows {
cache.insert(row.id, row.value);
}
cache
})
.map_err(|e| anyhow::anyhow!("Failed to load general table: {e}"))
}
/// Inserts or ignores a `Currency` row via the provided `pool`.
///
/// # Errors
///
/// Returns an error if the INSERT operation fails.
pub async fn add_currency(pool: &PgPool, currency: Currency) -> anyhow::Result<()> {
sqlx::query(
"INSERT INTO currency (id, precision, iso4217, name, currency_type) VALUES ($1, $2, $3, $4, $5::currency_type) ON CONFLICT (id) DO NOTHING"
)
.bind(currency.code.as_str())
.bind(i32::from(currency.precision))
.bind(i32::from(currency.iso4217))
.bind(currency.name.as_str())
.bind(CurrencyTypePg(currency.currency_type))
.execute(pool)
.awaitView on GitHub (pinned to 18893faf8b)
Solutions
- Run the current migrations so the `general` table and column types match this crate version.
- Confirm DATABASE_URL targets the intended cache database.
- If rows were written by a mismatched version, clear or migrate the `general` table before loading.
- Read the inner sqlx error: 'relation does not exist' means run migrations; 'error decoding' means schema drift.
Defensive patterns
Strategy: try-catch
Validate before calling
let exists: bool = sqlx::query_scalar(
"SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'general')",
).fetch_one(pool).await?;
if !exists {
return Err(anyhow::anyhow!("'general' table missing — run migrations"));
} Try / catch
match DatabaseQueries::load(&pool).await {
Err(e) if e.to_string().contains("relation \"general\" does not exist") => {
return Err(anyhow::anyhow!("cache schema missing — run migrations: {e}"));
}
result => result?,
} Prevention
- Run matching migrations whenever you upgrade the application version.
- Verify DATABASE_URL points at the intended cache database on startup.
- Avoid mixing cache databases written by incompatible schema versions.
- Inspect the inner sqlx error text to classify failures (missing table vs decode drift).
When it happens
Trigger: Calling `DatabaseQueries::load(pool)` when the connection fails, the `general` table doesn't exist (migrations missing), or GeneralRow decoding fails because rows were written by a different schema version (e.g. column type changed between releases).
Common situations: Loading the cache on startup against a database created by an older or newer schema version; pointing at the wrong database; transient network failure during a large fetch.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- Failed to load currencies: {e}
- Failed to load currency: {e}
- Failed to load instrument with id {instrument_id},error is:
- Failed to load instrument closes: {e}
- Failed to load order snapshot: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/ffe57a1d8ccc1944.
Report an issue: GitHub.