nautechsystems/nautilus_trader · error · anyhow::Error
Failed to migrate execution_transaction table
Error message
Failed to migrate execution_transaction table: {e} What it means
This error wraps failure executing one of the DDL migration statements (e.g. ALTER TABLE execution_transaction ADD COLUMN IF NOT EXISTS ...) inside the migration transaction. The library throws it to attribute the failure to the table migration step specifically.
Solutions
- Check the inner `{e}` for the failing statement and Postgres error code
- Verify the migration user has ALTER privileges on the table
- Inspect current column types via information_schema and reconcile with expected types
- Run migrations against a staging copy of the database first
Example fix
// before
.map_err(|e| anyhow::anyhow!("Failed to migrate execution_transaction table: {e}"))?;
// after
.map_err(|e| {
tracing::error!(error = %e, statement, "execution_transaction DDL failed");
anyhow::anyhow!("Failed to migrate execution_transaction table: {e}")
})?; Defensive patterns
Strategy: try-catch
Validate before calling
let can_alter = sqlx::query_scalar::<_, bool>(
"SELECT has_table_privilege(current_user, 'execution_transaction', 'ALTER')"
).fetch_one(&pool).await?;
if !can_alter { anyhow::bail!("migration user lacks ALTER privilege on execution_transaction"); } Try / catch
match ensure_execution_transaction_schema().await {
Ok(()) => (),
Err(e) if e.to_string().contains("Failed to migrate") => {
inspect_column_types(&pool).await?; // diagnose via information_schema
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Grant the migration user DDL privileges
- Test migrations against a staging copy of production schema
- Keep all environments on the same schema version before deploying
When it happens
Trigger: Executing the migration statements when a column already exists with an incompatible type, insufficient privileges for ALTER TABLE, the lock was lost (statement trigger on a different table), or syntax/type errors in a statement for the target Postgres version.
Common situations: Running with a DB user lacking DDL privileges; mixed schema versions where a column exists as a different type; older Postgres versions not supporting IF NOT EXISTS variants.
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 add pool event block hash storage
- Failed to inspect legacy execution transactions
- Failed to lock legacy execution transactions
- Failed to lock migrated intent
- Failed to persist migration evidence
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/0df7b7191efe9a4f.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/blockchain/src/cache/database.rs:3587
from_status TEXT,
to_status TEXT NOT NULL,
block_number BIGINT,
block_hash TEXT,
observed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CHECK (block_number IS NULL OR block_number >= 0),
CHECK (to_status IN (
'prepared', 'signed', 'broadcast', 'included', 'finalized',
'reverted', 'replaced', 'dropped', 'reorged', 'recoverable'
)),
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
);
}
View on GitHub (pinned to 18893faf8b)