nautechsystems/nautilus_trader · error
Failed to parse address: {e}
Error message
Failed to parse address: {e} What it means
`PoolIdentifier::to_address` converts an Address-variant identifier into an `alloy` `Address`. It errors either when called on the `PoolId` variant (a pool ID is not an address) or when the stored string fails checksummed address parsing.
Source
Thrown at crates/model/src/defi/pool_identifier.rs:193
}
/// Returns true if this is a `PoolId` variant (V4 pools).
#[must_use]
pub fn is_pool_id(&self) -> bool {
matches!(self, Self::PoolId(_))
}
/// Converts to native Address type (V2/V3 pools only).
///
/// Returns the underlying Address for use with alloy/ethers operations.
///
/// # Errors
///
/// Returns error if this is a `PoolId` variant or if parsing fails.
pub fn to_address(&self) -> anyhow::Result<Address> {
match self {
Self::Address(s) => Address::parse_checksummed(s.as_str(), None)
.map_err(|e| anyhow::anyhow!("Failed to parse address: {e}")),
Self::PoolId(_) => anyhow::bail!("Cannot convert PoolId variant to Address"),
}
}
/// Converts to native bytes array (V4 pools only).
///
/// Returns the 32-byte pool ID for use in V4-specific operations.
///
/// # Errors
///
/// Returns error if this is an Address variant or if hex decoding fails.
pub fn to_pool_id_bytes(&self) -> anyhow::Result<[u8; 32]> {
match self {
Self::PoolId(s) => {
let hex_str = s.strip_prefix("0x").unwrap_or(s.as_str());
hex::decode_array::<32>(hex_str)
.map_err(|e| anyhow::anyhow!("Failed to decode pool ID hex: {e}"))
}View on GitHub (pinned to 18893faf8b)
Solutions
- Match on the variant first: only call `to_address()` on `PoolIdentifier::Address`.
- For PoolId values use `to_pool_id_bytes()` instead.
- Store addresses in checksummed form (EIP-55) or parse with `Address::parse_checksummed(..., None)`/`Address::from_str` appropriately.
- Validate the address string with `validate_hex_string` and length 40 before constructing.
Example fix
// before
let addr = identifier.to_address()?; // panics into error for PoolId
// after
let addr = match &identifier {
PoolIdentifier::Address(_) => identifier.to_address()?,
PoolIdentifier::PoolId(_) => return Err(anyhow::anyhow!("expected Address variant")),
}; Defensive patterns
Strategy: type-guard
Validate before calling
fn expect_address(id: &PoolIdentifier) -> Option<&Ustr> {
match id { PoolIdentifier::Address(a) => Some(a), _ => None }
} Type guard
fn is_address_variant(id: &PoolIdentifier) -> bool {
matches!(id, PoolIdentifier::Address(_))
} Try / catch
match identifier.to_address() {
Ok(addr) => addr,
Err(e) if e.to_string().contains("PoolId") => fallback_pool_id_path(),
Err(e) => return Err(e),
} Prevention
- Keep variant knowledge in the type system (enum wrapper or newtype) so variant misuse cannot compile
- Store addresses in EIP-55 checksummed form so parse_checksummed succeeds
- Use exhaustive match on PoolIdentifier instead of blindly calling converters
When it happens
Trigger: Calling `to_address()` on a `PoolIdentifier::PoolId` value, or on an Address variant whose string is not a valid checksummed 20-byte hex address (wrong length, bad checksum casing, non-hex).
Common situations: Code that lost track of which variant it holds after parsing mixed pool data; addresses stored lowercased without EIP-55 checksums being parsed with `parse_checksummed`.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to decode pool ID hex: {e}
- Cannot convert PoolId variant to Address
- Cannot convert Address variant to PoolId bytes
- Router allowance {allowance} is below the swap amount {} for
- Input token {} balance {balance} is below the swap amount {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/640bb85a6556789d.
Report an issue: GitHub.