nautechsystems/nautilus_trader · error
Failed to insert into signal table: {e}
Error message
Failed to insert into signal table: {e} What it means
Raised by `add_signal` when the INSERT into the `signal` table fails. The sqlx execute error is converted into an anyhow::Error with this message, so any database-level constraint violation, type mismatch, or connectivity problem surfaces here.
Source
Thrown at crates/infrastructure/src/sql/queries.rs:1592
name, value, ts_event, ts_init, created_at, updated_at
) VALUES (
$1, $2, $3, $4, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
)
ON CONFLICT (id)
DO UPDATE
SET
name = $1, value = $2, ts_event = $3, ts_init = $4,
updated_at = CURRENT_TIMESTAMP
"#,
)
.bind(signal.name.to_string())
.bind(signal.value.clone())
.bind(signal.ts_event.to_string())
.bind(signal.ts_init.to_string())
.execute(pool)
.await
.map(|_| ())
.map_err(|e| anyhow::anyhow!("Failed to insert into signal table: {e}"))
}
/// Loads all `Signal` entries by `name` via the provided `pool`.
///
/// # Errors
///
/// Returns an error if the SQL SELECT or deserialization fails.
pub async fn load_signals(pool: &PgPool, name: &str) -> anyhow::Result<Vec<Signal>> {
sqlx::query_as::<_, SignalRow>(
r#"SELECT * FROM "signal" WHERE name = $1 ORDER BY ts_init ASC"#,
)
.bind(name)
.fetch_all(pool)
.await
.map(|rows| rows.into_iter().map(|row| row.0).collect())
.map_err(|e| anyhow::anyhow!("Failed to load signals: {e}"))
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Read the embedded sqlx error to identify constraint/table issues.
- Run the library's SQL migrations to ensure the `signal` table exists with expected columns.
- Validate the signal fields (name, value, ts_event, ts_init) are non-null before insert.
- Check the database is writable and the pool connection is healthy.
Example fix
// before
add_signal(&pool, &signal).await?;
// after
if signal.name.is_empty() { anyhow::bail!("signal name required"); }
add_signal(&pool, &signal).await
.map_err(|e| e.context(format!("adding signal {}", signal.name)))?; 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 = 'signal')")
.fetch_one(pool).await?;
anyhow::ensure!(exists, "signal table missing; run migrations");
anyhow::ensure!(!signal.name.is_empty(), "signal name required"); Try / catch
if let Err(e) = add_signal(&pool, &signal).await {
tracing::error!("signal insert failed: {e:#}");
return Err(e.context("signal persistence failed"));
} Prevention
- Keep migrations in sync with the library version
- Validate non-null signal fields before insert
- Ensure the DB is not read-only
- Log the full error chain ({e:#}) for diagnosis
When it happens
Trigger: Calling `add_signal(pool, signal)` when the `signal` table is missing, a NOT NULL/constraint is violated, the pool is dead, or a serialization of bound values (name, value, timestamps as strings) is rejected by PostgreSQL.
Common situations: Schema drift after upgrading the library without rerunning migrations; writing signals with null name/value; database in read-only mode; connection dropped mid-write.
Related errors
- Failed to insert into block table: {e}
- Failed to batch insert into block table: {e}
- Failed to batch insert into pool_event_block table: {e}
- Failed to insert into dex table: {e}
- Failed to insert into pool table: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/38a786956d446048.
Report an issue: GitHub.