nautechsystems/nautilus_trader · error

Token manifest address has no contract identity

Error message

Token manifest address has no contract identity

What it means

After parsing, the validator requires every manifest token's address to appear in the set of addresses pinned by manifest.contracts — tokens must reference an actual contract entry with a runtime code hash. This error means the token's address parses but has no matching contract entry, so its deployed code is not verified.

Source

Thrown at crates/adapters/blockchain/src/rpc/verification.rs:1356

    for required in [
        BlockchainContractRole::Router,
        BlockchainContractRole::Factory,
        BlockchainContractRole::WrappedNative,
        BlockchainContractRole::Quote,
        BlockchainContractRole::Token,
        BlockchainContractRole::Pool,
    ] {
        anyhow::ensure!(
            roles.contains(&required),
            "Deployment manifest is missing a required role"
        );
    }

    for token in &manifest.tokens {
        let address = Address::from_str(&token.address)
            .map_err(|_| anyhow::anyhow!("Token manifest address is invalid"))?;
        anyhow::ensure!(
            contract_addresses.contains(&address),
            "Token manifest address has no contract identity"
        );
        anyhow::ensure!(
            !token.name.trim().is_empty()
                && !token.symbol.trim().is_empty()
                && matches!(token.asset_role.as_str(), "base" | "quote" | "both"),
            "Token manifest identity or asset role is invalid"
        );
    }

    for pool in &manifest.pools {
        for address in [
            &pool.address,
            &pool.token0,
            &pool.token1,
            &pool.factory,
            &pool.quote_contract,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Add a contract entry for the token address with role Token (or the appropriate role) and its runtime_code_hash
  2. Make the token address byte-identical to the address in its contract entry (compare lowercase hex)
  3. Regenerate the manifest programmatically so tokens and contracts are emitted from one source

Example fix

// before
"tokens": [{"address": "0xabc..."}], "contracts": [/* no 0xabc... */]
// after
"tokens": [{"address": "0xabc..."}], "contracts": [{"address": "0xabc...", "role": "token", "runtime_code_hash": "0x..."}]
Defensive patterns

Strategy: validation

Validate before calling

fn tokens_pinned(manifest: &Manifest) -> bool {
    let pinned: HashSet<Address> = manifest.contracts.iter()
        .filter_map(|c| Address::from_str(&c.address).ok()).collect();
    manifest.tokens.iter().all(|t| Address::from_str(&t.address).map(|a| pinned.contains(&a)).unwrap_or(false))
}

Try / catch

match validate_manifest(&config) {
    Err(e) if e.to_string().contains("no contract identity") => {
        eprintln!("add a contract entry for the token address: {e}");
    }
    Err(e) => return Err(e),
    Ok(v) => v,
}

Prevention

When it happens

Trigger: Manifest verification where manifest.tokens lists an address absent from manifest.contracts — e.g. adding a token entry without adding its contract entry, or the token contract entry uses a different (typo'd/checksummed differently) address string.

Common situations: Hand-adding a new token to the manifest without pinning its contract; address copied with different casing/typo between tokens[] and contracts[]; token address pointing at the wrapper or router rather than the token contract itself.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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