{"record":{"id":"7e3c5b3053aa2ee1","repo":"nautechsystems/nautilus_trader","slug":"provider-operator-id-is-required","errorCode":null,"errorMessage":"Provider operator ID is required","messagePattern":"Provider operator ID is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/rpc/verification.rs","lineNumber":1438,"sourceCode":"\n    for purpose in [\"swap_sell\", \"swap_buy\"] {\n        anyhow::ensure!(\n            manifest\n                .call_edges\n                .iter()\n                .any(|edge| edge.purpose == purpose),\n            \"Deployment manifest is missing a swap call graph\"\n        );\n    }\n    Ok(())\n}\n\nfn validate_identity(identity: &BlockchainProviderIdentity) -> anyhow::Result<()> {\n    anyhow::ensure!(\n        !identity.provider_id.trim().is_empty(),\n        \"Provider ID is required\"\n    );\n    anyhow::ensure!(\n        !identity.operator_id.trim().is_empty(),\n        \"Provider operator ID is required\"\n    );\n    anyhow::ensure!(\n        !identity.failure_domain_ids.is_empty()\n            && identity\n                .failure_domain_ids\n                .iter()\n                .all(|domain| !domain.trim().is_empty()),\n        \"Provider failure domains must contain nonempty opaque IDs\"\n    );\n    ensure_distinct(\n        identity.failure_domain_ids.iter().map(String::as_str),\n        \"failure-domain IDs within one provider\",\n    )\n}\n\nfn ensure_distinct<'a>(","sourceCodeStart":1420,"sourceCodeEnd":1456,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/rpc/verification.rs#L1420-L1456","documentation":"A blockchain provider identity must include a nonempty operator_id; the check trims whitespace, so blank values fail. The operator_id distinguishes the operator entity running the provider from the provider itself and is required for identity resolution and failure-domain bookkeeping.","triggerScenarios":"Validating a BlockchainProviderIdentity whose operator_id is missing, empty, or whitespace-only; the provider_id check passes first, so this fires only for identities that already have a valid provider_id.","commonSituations":"Config templates with operator_id left blank; multi-operator setups where the operator field was never filled for a new deployment; deserialization from YAML/JSON where the key was omitted and defaulted to an empty string; environment variables not exported before launch.","solutions":["Set operator_id to a nonempty identifier for the operating entity in the identity/config","Ensure the environment variable or secret backing operator_id is exported and nonempty at startup","If identities are templated, add operator_id to the template and validate before deploy","Run the identity validation early in startup so missing identity fields surface before use"],"exampleFix":"// before\n{\"provider_id\": \"alchemy-mainnet\", \"operator_id\": \"\"}\n// after\n{\"provider_id\": \"alchemy-mainnet\", \"operator_id\": \"ops-team-alpha\"}","handlingStrategy":"validation","validationCode":"if identity.operator_id.trim().is_empty() {\n    return Err(\"operator_id must be a nonempty identifier\".into());\n}","typeGuard":"fn has_operator_id(identity: &BlockchainProviderIdentity) -> bool {\n    !identity.operator_id.trim().is_empty()\n}","tryCatchPattern":"match validate_identity(&identity) {\n    Err(e) if e.to_string().contains(\"Provider operator ID is required\") => {\n        eprintln!(\"Set operator_id in the provider config/environment before starting\");\n    }\n    Err(e) => return Err(e),\n    Ok(()) => {}\n}","preventionTips":["Include operator_id in every identity template and config schema","Validate the full identity (provider_id, operator_id, failure domains) at startup","Verify env vars for operator identity are exported in deployment scripts"],"tags":["blockchain","identity","config"],"backgroundTag":"empty-required-field","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}