nautechsystems/nautilus_trader · error · anyhow::Error
Failed to read execution schema version
Error message
Failed to read execution schema version: {e} What it means
This error wraps failure reading the installed schema version from execution_schema_version (`SELECT version ... WHERE component = 'evm_execution'`). The library throws it to distinguish version-lookup failures from DDL failures during migration.
Solutions
- Ensure execution_schema_version table exists with a smallint version column (create it in the same migration)
- Verify connectivity and SELECT privileges on execution_schema_version
- Compare the column type to i16 (SMALLINT); alter if it was created as INTEGER
- Re-run migrations in order so version tracking is initialized before it is read
Example fix
// before
.map_err(|e| anyhow::anyhow!("Failed to read execution schema version: {e}"))?;
// after
.map_err(|e| {
tracing::error!(error = %e, "execution_schema_version read failed");
anyhow::anyhow!("Failed to read execution schema version: {e}")
})?; Defensive patterns
Strategy: try-catch
Validate before calling
let has_version_table = sqlx::query_scalar::<_, bool>(
"SELECT to_regclass('execution_schema_version') IS NOT NULL"
).fetch_one(&pool).await?;
if !has_version_table { anyhow::bail!("execution_schema_version missing; initialize version tracking first"); } Try / catch
match db.ensure_execution_transaction_schema().await {
Ok(()) => (),
Err(e) if e.to_string().contains("Failed to read execution schema version") => {
init_execution_schema_version_table(&pool).await?;
db.ensure_execution_transaction_schema().await?;
}
Err(e) => return Err(e),
} Prevention
- Create execution_schema_version in the same migration that creates the table
- Use SMALLINT for the version column to match query_scalar::<_, i16>
- Never manually edit or drop version tracking tables
When it happens
Trigger: ensure_execution_transaction_schema runs and the execution_schema_version table is missing, the version column has an unexpected type (query_scalar expects i16), or the query fails due to connectivity/permissions.
Common situations: Partially applied earlier migration that created execution_transaction but not execution_schema_version; manual schema edits; smallint vs integer type mismatch in the version column.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- Execution verification schema version
- Cannot safely migrate
- Execution intent uses unsupported schema version
- Execution payload changed during migration
- Execution payload migration found
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/2c03433f5844605f.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/blockchain/src/cache/database.rs:3596
)),
UNIQUE (intent_id, transition_key)
)
",
] {
sqlx::query(statement)
.execute(&mut *transaction)
.await
.map_err(|e| {
anyhow::anyhow!("Failed to migrate execution_transaction table: {e}")
})?;
}
let installed_version = sqlx::query_scalar::<_, i16>(
"SELECT version FROM execution_schema_version WHERE component = 'evm_execution'",
)
.fetch_optional(&mut *transaction)
.await
.map_err(|e| anyhow::anyhow!("Failed to read execution schema version: {e}"))?;
if let Some(installed_version) = installed_version
&& installed_version > EXECUTION_SCHEMA_VERSION
{
anyhow::bail!(
"Execution schema version {} is newer than supported version {EXECUTION_SCHEMA_VERSION}",
installed_version
);
}
let unresolved_legacy = sqlx::query_scalar::<_, i64>(
"
SELECT COUNT(*)
FROM execution_transaction
WHERE status IN ('pending', 'included', 'reverted')
",
)
.fetch_one(&mut *transaction)
.awaitView on GitHub (pinned to 18893faf8b)