sigoden/aichat · error
Already in a session, please run '.exit session' first to…
Error message
Already in a session, please run '.exit session' first to exit the current session.
What it means
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.
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
Example fix
// before
config.write().use_session(Some("work"))?; // fails if already in a session
// after
{
let mut cfg = config.write();
if cfg.session.is_some() {
cfg.exit_session()?;
}
cfg.use_session(Some("work"))?;
} Defensive patterns
Strategy: validation
Validate before calling
fn can_start_session(cfg: &GlobalConfig) -> bool {
cfg.read().session.is_none()
} Try / catch
if let Err(e) = config.write().use_session(Some("work")) {
if e.to_string().contains("Already in a session") {
config.write().exit_session()?;
config.write().use_session(Some("work"))?;
} else { return Err(e); }
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- No session
- Unable to continue the response
- Unable to regenerate the response
- Cannot perform this operation because the session has…
- No chat response to copy
AI-assisted analysis of sigoden/aichat@82976d349a (2026-09-09).
Data as JSON: /api/errors/f98b115f6898b0ed.
Report an issue: GitHub.
Appendix: source
Thrown at src/config/mod.rs:1075
}
}
}
if with_builtin {
names.extend(Role::list_builtin_role_names());
}
let mut names: Vec<_> = names.into_iter().collect();
names.sort_unstable();
names
}
pub fn has_role(name: &str) -> bool {
let names = Self::list_roles(true);
names.contains(&name.to_string())
}
pub fn use_session(&mut self, session_name: Option<&str>) -> Result<()> {
if self.session.is_some() {
bail!(
"Already in a session, please run '.exit session' first to exit the current session."
);
}
let mut session;
match session_name {
None | Some(TEMP_SESSION_NAME) => {
let session_file = self.session_file(TEMP_SESSION_NAME);
if session_file.exists() {
remove_file(session_file).with_context(|| {
format!("Failed to cleanup previous '{TEMP_SESSION_NAME}' session")
})?;
}
session = Some(Session::new(self, TEMP_SESSION_NAME));
}
Some(name) => {
let session_path = self.session_file(name);
if !session_path.exists() {
session = Some(Session::new(self, name));View on GitHub (pinned to 82976d349a)