nautechsystems/nautilus_trader · error · anyhow::Error

Deployment manifest pool does not use the pinned pool, facto

Error message

Deployment manifest pool does not use the pinned pool, factory, and quote identities

What it means

Beyond parseability, each manifest pool must match the pinned identities: the pool address must be registered under BlockchainContractRole::Pool, the factory must equal the deployment's pinned factory, and the quote contract must equal the pinned quote contract. Any mismatch fails validation, keeping manifest contents consistent with the configured contract roles.

Source

Thrown at crates/adapters/blockchain/src/execution/client.rs:472

        for limit in config.quote_spend_limits.as_deref().unwrap_or_default() {
            let spend_token = validate_address(&limit.spend_token)?;
            anyhow::ensure!(
                token_decimals.get(&spend_token) == Some(&limit.spend_token_decimals),
                "Quote spend limit decimals do not match the deployment manifest"
            );
        }

        let pool_contracts = role_addresses(BlockchainContractRole::Pool)?;

        for pool in &manifest.pools {
            let pool_address = Address::from_str(&pool.address)
                .map_err(|_| anyhow::anyhow!("Deployment manifest pool address is invalid"))?;
            let pool_factory = Address::from_str(&pool.factory)
                .map_err(|_| anyhow::anyhow!("Deployment manifest pool factory is invalid"))?;
            let pool_quote = Address::from_str(&pool.quote_contract).map_err(|_| {
                anyhow::anyhow!("Deployment manifest pool quote contract is invalid")
            })?;
            anyhow::ensure!(
                pool_contracts.contains(&pool_address)
                    && pool_factory == factory
                    && pool_quote == quote_contract,
                "Deployment manifest pool does not use the pinned pool, factory, and quote identities"
            );
        }
        Ok(())
    }

    async fn fetch_native_currency_balance(&self) -> anyhow::Result<Money> {
        let balance_u256 = self
            .http_rpc_client
            .get_balance_with_timeout(&self.wallet_address, None, Some(EXECUTION_RPC_TIMEOUT_SECS))
            .await?;

        let native_currency = self.chain.native_currency();

        Money::from_u256(balance_u256, native_currency).map_err(Into::into)

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Regenerate the deployment manifest from the current pinned contract set
  2. Update config contract roles (Pool/factory/quote) to the deployment the manifest describes
  3. Remove the stale pool entry from the manifest
Defensive patterns

Strategy: validation

Validate before calling

for pool in &manifest.pools {
    assert!(pool_contracts.contains(&Address::from_str(&pool.address)?), "pool not registered under Pool role");
    assert_eq!(Address::from_str(&pool.factory)?, factory, "factory mismatch");
    assert_eq!(Address::from_str(&pool.quote_contract)?, quote_contract, "quote mismatch");
}

Prevention

When it happens

Trigger: Calling preflight/validate_manifest_contracts where a manifest pool's address is not in the Pool-role address list, or pool.factory != factory, or pool.quote_contract != quote_contract.

Common situations: Manifest generated for a previous deployment whose factory/quote contracts were upgraded; pool registered under a different role; stale manifest committed after rotating contracts.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/cc04748224bedae2. Report an issue: GitHub.