{"record":{"id":"075438bb5862d048","repo":"nautechsystems/nautilus_trader","slug":"no-instrument-id-for-command","errorCode":null,"errorMessage":"No instrument ID for command","messagePattern":"No instrument ID for command","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/common/src/messages/execution/mod.rs","lineNumber":202,"sourceCode":"    }\n\n    /// Returns the instrument ID for the command.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the command is `QueryAccount` which does not have an instrument ID.\n    #[must_use]\n    pub const fn instrument_id(&self) -> InstrumentId {\n        match self {\n            Self::SubmitOrder(command) => command.instrument_id,\n            Self::SubmitOrderList(command) => command.instrument_id,\n            Self::ModifyOrder(command) => command.instrument_id,\n            Self::ModifyOrders(command) => command.instrument_id,\n            Self::CancelOrder(command) => command.instrument_id,\n            Self::CancelOrders(command) => command.instrument_id,\n            Self::CancelAllOrders(command) => command.instrument_id,\n            Self::QueryOrder(command) => command.instrument_id,\n            Self::QueryAccount(_) => panic!(\"No instrument ID for command\"),\n        }\n    }\n\n    #[must_use]\n    pub const fn ts_init(&self) -> UnixNanos {\n        match self {\n            Self::SubmitOrder(command) => command.ts_init,\n            Self::SubmitOrderList(command) => command.ts_init,\n            Self::ModifyOrder(command) => command.ts_init,\n            Self::ModifyOrders(command) => command.ts_init,\n            Self::CancelOrder(command) => command.ts_init,\n            Self::CancelOrders(command) => command.ts_init,\n            Self::CancelAllOrders(command) => command.ts_init,\n            Self::QueryOrder(command) => command.ts_init,\n            Self::QueryAccount(command) => command.ts_init,\n        }\n    }\n","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/messages/execution/mod.rs#L184-L220","documentation":"`ExecutionCommand::instrument_id()` is a total accessor over all execution command variants; because `QueryAccount` is account-scoped and carries no instrument ID, matching it reaches an explicit `panic!`. The doc-comment documents this: the method must only be called on commands that are instrument-scoped. It signals a caller-side dispatch bug, not bad user input.","triggerScenarios":"Calling `command.instrument_id()` on an `ExecutionCommand::QueryAccount(_)` — e.g. in `process_trading_command` or any routing/logging code that calls the accessor before filtering out account-scoped commands.","commonSituations":"New command handlers that iterate all `ExecutionCommand` variants generically; refactors that add a `QueryAccount` path without excluding it from instrument-scoped logic; debug logging of commands that blindly extracts instrument_id.","solutions":["Match the command variant first and handle `QueryAccount` separately before calling `instrument_id()`.","Pattern-match and return `Option<InstrumentId>` at the call site instead of using the total accessor.","Reorder routing logic so account commands are processed before any instrument_id extraction.","If the panic occurs, log the command variant to confirm an unhandled QueryAccount is reaching instrument-scoped processing."],"exampleFix":"// before\nlet instrument_id = command.instrument_id();\nprocess(instrument_id);\n// after\nmatch command {\n    ExecutionCommand::QueryAccount(cmd) => process_account(cmd),\n    _ => process(command.instrument_id()),\n}","handlingStrategy":"type-guard","validationCode":"// Guard before calling the accessor\nif matches!(command, ExecutionCommand::QueryAccount(_)) {\n    return; // account commands have no instrument_id\n}\nlet instrument_id = command.instrument_id();","typeGuard":"fn command_instrument_id(cmd: &ExecutionCommand) -> Option<InstrumentId> {\n    match cmd {\n        ExecutionCommand::QueryAccount(_) => None,\n        other => Some(other.instrument_id()),\n    }\n}","tryCatchPattern":null,"preventionTips":["Never call total accessors on enum sum types without excluding documented variants first","Handle QueryAccount in a dedicated branch of command-processing code","Add exhaustive-match tests covering every ExecutionCommand variant"],"tags":["rust","panic","execution-commands","dispatch"],"backgroundTag":"unsupported-operation","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"}