nautechsystems/nautilus_trader · error
Token manifest identity or asset role is invalid
Error message
Token manifest identity or asset role is invalid
What it means
Each manifest token must have a non-empty trimmed name, a non-empty trimmed symbol, and an asset_role that is exactly one of "base", "quote", or "both". This error means the token exists and is pinned, but its identity metadata or asset role is missing/misspelled, so the adapter cannot classify the token as a swap base or quote asset.
Source
Thrown at crates/adapters/blockchain/src/rpc/verification.rs:1360
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,
] {
let address = Address::from_str(address)
.map_err(|_| anyhow::anyhow!("Pool manifest address is invalid"))?;
anyhow::ensure!(View on GitHub (pinned to 18893faf8b)
Solutions
- Set asset_role to exactly "base", "quote", or "both" (lowercase)
- Fill in non-empty name and symbol (trim whitespace)
- Regenerate the manifest with the generator that emits the expected role vocabulary
Example fix
// before
{"address": "0xabc...", "name": "", "symbol": "USDC", "asset_role": "Base"}
// after
{"address": "0xabc...", "name": "USD Coin", "symbol": "USDC", "asset_role": "quote"} Defensive patterns
Strategy: validation
Validate before calling
fn token_metadata_ok(t: &TokenEntry) -> bool {
!t.name.trim().is_empty()
&& !t.symbol.trim().is_empty()
&& matches!(t.asset_role.as_str(), "base" | "quote" | "both")
}
assert!(manifest.tokens.iter().all(token_metadata_ok)); Try / catch
match validate_manifest(&config) {
Err(e) if e.to_string().contains("identity or asset role") => {
eprintln!("set non-empty name/symbol and asset_role in {{base,quote,both}}: {e}");
}
Err(e) => return Err(e),
Ok(v) => v,
} Prevention
- Use only the lowercase literals base/quote/both for asset_role
- Never ship placeholder or empty name/symbol values
- Enforce token metadata with a JSON schema check before verification
When it happens
Trigger: Manifest verification where a token entry has an empty or whitespace-only name/symbol, or asset_role is absent, empty, or any string other than base/quote/both — e.g. asset_role: "Base" (wrong case), "pricing", or "".
Common situations: Hand-adding a token with placeholder metadata; a manifest generator emitting camelCase or a different role vocabulary; truncated JSON edit leaving empty strings; copying a token entry between manifests that use different role conventions.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Chart function must be callable, was {type(f)}
- Chart function must be callable, was {type(func)}
- Chart '{name}' not found.{suggestion_text} Available charts:
- plotly is required for visualization. Install it with: pip i
- A BacktestNode is required for the bars_with_fills chart
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/3296cb36b7ef3bfb.
Report an issue: GitHub.