nautechsystems/nautilus_trader · error · anyhow::Error
Failed to insert into token table: {e}
Error message
Failed to insert into token table: {e} What it means
Database write error in the blockchain cache's token insert: the SQLx upsert of a token row (chain_id, address, name, symbol, decimals) into PostgreSQL failed; the driver error is embedded in the message.
Source
Thrown at crates/adapters/blockchain/src/cache/database.rs:1163
chain_id, address, name, symbol, decimals
) VALUES ($1, $2, $3, $4, $5)
ON CONFLICT (chain_id, address)
DO UPDATE
SET
name = $3,
symbol = $4,
decimals = $5
",
)
.bind(token.chain.chain_id as i32)
.bind(token.address.to_string())
.bind(token.name.as_str())
.bind(token.symbol.as_str())
.bind(i32::from(token.decimals))
.execute(&self.pool)
.await
.map(|_| ())
.map_err(|e| anyhow::anyhow!("Failed to insert into token table: {e}"))
}
/// Records an invalid token address with associated error information.
///
/// # Errors
///
/// Returns an error if the database insertion fails.
pub async fn add_invalid_token(
&self,
chain_id: u32,
address: &Address,
error_string: &str,
) -> anyhow::Result<()> {
sqlx::query(
"
INSERT INTO token (
chain_id, address, error
) VALUES ($1, $2, $3)View on GitHub (pinned to 18893faf8b)
Solutions
- Read the wrapped `{e}`: 'value too long' → truncate/validate name and symbol against column limits before insert
- Use ON CONFLICT (address) DO UPDATE or dedupe tokens before upsert for replay safety
- Run migrations to ensure the token table matches the code's expected schema
- Confirm DB connectivity and INSERT privileges for the configured role
Example fix
// before .bind(token.name.as_str()) // may exceed VARCHAR(64) // after .bind(token.name.chars().take(64).collect::<String>())
Defensive patterns
Strategy: validation
Validate before calling
const MAX_NAME: usize = 64; // match the column limit anyhow::ensure!(!token.address.is_empty(), "token address empty"); anyhow::ensure!(token.name.chars().count() <= MAX_NAME && token.symbol.chars().count() <= 32, "token metadata exceeds column length");
Type guard
fn token_valid(t: &Token) -> bool {
!t.address.is_empty()
&& t.name.chars().count() <= 64
&& t.symbol.chars().count() <= 32
} Try / catch
if let Err(e) = db.insert_token(&token).await {
if e.to_string().contains("value too long") {
let mut t = token.clone(); t.name.truncate(64);
db.insert_token(&t).await?;
} else { return Err(e); }
} Prevention
- Truncate or validate name/symbol against column limits — on-chain metadata is unbounded
- Use upsert semantics keyed on address so rediscovery is idempotent
- Run migrations before token discovery writes
- Escape/handle multi-byte characters safely (sqlx handles this; avoid manual SQL concatenation)
When it happens
Trigger: Calling the token insert when `token.name` or `token.symbol` exceed column length limits (VARCHAR overflow), `decimals` doesn't fit i32 (it is cast with i32::from(u8) so unlikely), the token address violates a unique constraint/cast, or the pool connection fails during execute.
Common situations: On-chain token metadata with very long names/symbols overflowing VARCHAR(n); replaying token discovery duplicating the address key; fresh database missing the token table; DB role without INSERT privilege.
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/5359b545631a33ad.
Report an issue: GitHub.