{"record":{"id":"f98b115f6898b0ed","repo":"sigoden/aichat","slug":"already-in-a-session-please-run-exit-session-f","errorCode":null,"errorMessage":"Already in a session, please run '.exit session' first to exit the current session.","messagePattern":"Already in a session, please run '\\.exit session' first to exit the current session\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/config/mod.rs","lineNumber":1075,"sourceCode":"                }\n            }\n        }\n        if with_builtin {\n            names.extend(Role::list_builtin_role_names());\n        }\n        let mut names: Vec<_> = names.into_iter().collect();\n        names.sort_unstable();\n        names\n    }\n\n    pub fn has_role(name: &str) -> bool {\n        let names = Self::list_roles(true);\n        names.contains(&name.to_string())\n    }\n\n    pub fn use_session(&mut self, session_name: Option<&str>) -> Result<()> {\n        if self.session.is_some() {\n            bail!(\n                \"Already in a session, please run '.exit session' first to exit the current session.\"\n            );\n        }\n        let mut session;\n        match session_name {\n            None | Some(TEMP_SESSION_NAME) => {\n                let session_file = self.session_file(TEMP_SESSION_NAME);\n                if session_file.exists() {\n                    remove_file(session_file).with_context(|| {\n                        format!(\"Failed to cleanup previous '{TEMP_SESSION_NAME}' session\")\n                    })?;\n                }\n                session = Some(Session::new(self, TEMP_SESSION_NAME));\n            }\n            Some(name) => {\n                let session_path = self.session_file(name);\n                if !session_path.exists() {\n                    session = Some(Session::new(self, name));","sourceCodeStart":1057,"sourceCodeEnd":1093,"githubUrl":"https://github.com/sigoden/aichat/blob/82976d349ad97ac9aae0655ad631dace5e2a6385/src/config/mod.rs#L1057-L1093","documentation":"GlobalConfig::use_session (src/config/mod.rs:1075) refuses to start a new session while self.session is already Some, i.e. the REPL is already inside an active session. The library enforces at most one live session at a time and tells the user to exit it first. This is an explicit state-machine guard, not a resource failure.","triggerScenarios":"Calling `.session <name>` (or use_session) while a session is already active; invoking session start twice in a script without closing the first; a REPL hook that auto-starts a session colliding with a user-initiated `.session` command.","commonSituations":"Long-running REPL where the user forgot an earlier `.session` call; automation that issues `.session` on each command; recovering from a crashed wrapper that left session state logically open in the same process.","solutions":["Run `.exit session` (or exit_session) to close the current session, then call use_session again","If you want to keep working, reuse the current session instead of starting a new one","Check with `self.session.is_some()` / an equivalent accessor before attempting to start a session"],"exampleFix":"// before\nconfig.write().use_session(Some(\"work\"))?; // fails if already in a session\n// after\n{\n    let mut cfg = config.write();\n    if cfg.session.is_some() {\n        cfg.exit_session()?;\n    }\n    cfg.use_session(Some(\"work\"))?;\n}","handlingStrategy":"validation","validationCode":"fn can_start_session(cfg: &GlobalConfig) -> bool {\n    cfg.read().session.is_none()\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = config.write().use_session(Some(\"work\")) {\n    if e.to_string().contains(\"Already in a session\") {\n        config.write().exit_session()?;\n        config.write().use_session(Some(\"work\"))?;\n    } else { return Err(e); }\n}","preventionTips":["Track session state in your REPL wrapper","Always pair session start with exit_session in automation","Expose the current session name in your UI to avoid double-starts"],"tags":["session","state","repl"],"backgroundTag":"invalid-state-transition","analyzedSha":"82976d349ad97ac9aae0655ad631dace5e2a6385","analyzedAt":"2026-09-09T18:33:06.139Z","contentChangedAt":"2026-09-09T18:33:06.139Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}