{"record":{"id":"68175f4ec77c88d9","repo":"zed-industries/zed","slug":"only-call-run-once","errorCode":null,"errorMessage":"Only call run once","messagePattern":"Only call run once","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/askpass/src/askpass.rs","lineNumber":193,"sourceCode":"            askpass_task,\n            askpass_kill_master_rx: Some(askpass_kill_master_rx),\n            askpass_opened_rx: Some(askpass_opened_rx),\n            executor,\n        })\n    }\n\n    // This will run the askpass task forever, resolving as many authentication requests as needed.\n    // The caller is responsible for examining the result of their own commands and cancelling this\n    // future when this is no longer needed. Note that this can only be called once, but due to the\n    // drop order this takes an &mut, so you can `drop()` it after you're done with the master process.\n    //\n    // When `timeout` is provided, this resolves with `AskPassResult::Timedout` if no askpass prompt\n    // has been opened within that duration. This is intended for connection establishment (e.g.\n    // SSH), where \"no prompt and no connection\" indicates an unreachable host. Callers wrapping\n    // commands that may legitimately run for a long time without prompting (e.g. git) should pass\n    // `None` and rely on the command's own completion instead.\n    pub async fn run(&mut self, timeout: Option<Duration>) -> AskPassResult {\n        let askpass_opened_rx = self.askpass_opened_rx.take().expect(\"Only call run once\");\n        let askpass_kill_master_rx = self\n            .askpass_kill_master_rx\n            .take()\n            .expect(\"Only call run once\");\n        let executor = self.executor.clone();\n        let timer = async move {\n            match timeout {\n                Some(timeout) => executor.timer(timeout).await,\n                None => std::future::pending().await,\n            }\n        };\n\n        select_biased! {\n            _ = askpass_opened_rx.fuse() => {\n                // Note: this await can only resolve after we are dropped.\n                askpass_kill_master_rx.await.ok();\n                AskPassResult::CancelledByUser\n            }","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/zed-industries/zed/blob/f4178619acd0d47ea1f76a2025c42962c6d6638c/crates/askpass/src/askpass.rs#L175-L211","documentation":"Contract guard in AskPass::run: the askpass master process and channels are stored as Options that run() takes (via take/replace semantics), so calling run() a second time would find them already consumed. Firing means a caller reused an AskPass instance after its first run.","triggerScenarios":"Thrown at crates/askpass/src/askpass.rs:193 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Create a new AskPass instance for each authentication session","Call run() exactly once per instance and drop the instance when finished"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"f4178619acd0d47ea1f76a2025c42962c6d6638c","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}