{"record":{"id":"3296cb36b7ef3bfb","repo":"nautechsystems/nautilus_trader","slug":"token-manifest-identity-or-asset-role-is-invalid","errorCode":null,"errorMessage":"Token manifest identity or asset role is invalid","messagePattern":"Token manifest identity or asset role is invalid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/rpc/verification.rs","lineNumber":1360,"sourceCode":"        BlockchainContractRole::WrappedNative,\n        BlockchainContractRole::Quote,\n        BlockchainContractRole::Token,\n        BlockchainContractRole::Pool,\n    ] {\n        anyhow::ensure!(\n            roles.contains(&required),\n            \"Deployment manifest is missing a required role\"\n        );\n    }\n\n    for token in &manifest.tokens {\n        let address = Address::from_str(&token.address)\n            .map_err(|_| anyhow::anyhow!(\"Token manifest address is invalid\"))?;\n        anyhow::ensure!(\n            contract_addresses.contains(&address),\n            \"Token manifest address has no contract identity\"\n        );\n        anyhow::ensure!(\n            !token.name.trim().is_empty()\n                && !token.symbol.trim().is_empty()\n                && matches!(token.asset_role.as_str(), \"base\" | \"quote\" | \"both\"),\n            \"Token manifest identity or asset role is invalid\"\n        );\n    }\n\n    for pool in &manifest.pools {\n        for address in [\n            &pool.address,\n            &pool.token0,\n            &pool.token1,\n            &pool.factory,\n            &pool.quote_contract,\n        ] {\n            let address = Address::from_str(address)\n                .map_err(|_| anyhow::anyhow!(\"Pool manifest address is invalid\"))?;\n            anyhow::ensure!(","sourceCodeStart":1342,"sourceCodeEnd":1378,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/rpc/verification.rs#L1342-L1378","documentation":"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.","triggerScenarios":"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 \"\".","commonSituations":"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.","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"],"exampleFix":"// before\n{\"address\": \"0xabc...\", \"name\": \"\", \"symbol\": \"USDC\", \"asset_role\": \"Base\"}\n// after\n{\"address\": \"0xabc...\", \"name\": \"USD Coin\", \"symbol\": \"USDC\", \"asset_role\": \"quote\"}","handlingStrategy":"validation","validationCode":"fn token_metadata_ok(t: &TokenEntry) -> bool {\n    !t.name.trim().is_empty()\n        && !t.symbol.trim().is_empty()\n        && matches!(t.asset_role.as_str(), \"base\" | \"quote\" | \"both\")\n}\nassert!(manifest.tokens.iter().all(token_metadata_ok));","typeGuard":null,"tryCatchPattern":"match validate_manifest(&config) {\n    Err(e) if e.to_string().contains(\"identity or asset role\") => {\n        eprintln!(\"set non-empty name/symbol and asset_role in {{base,quote,both}}: {e}\");\n    }\n    Err(e) => return Err(e),\n    Ok(v) => v,\n}","preventionTips":["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"],"tags":["validation","manifest","enum"],"backgroundTag":"invalid-enum-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}