fix: address CI test failure and add empty-session error message

- Fix latest_session_alias_resolves_most_recent_managed_session test:
  the test created sessions with 0 messages, which are now filtered out
  by the message_count > 0 check in latest_session_excluding(). Updated
  the test to call push_user_text() before saving so sessions have
  at least one message and are findable by /resume latest.

- Add distinct error message when all sessions are empty (0 messages).
  Previously, the same "no managed sessions found" message was returned
  whether there were zero sessions or all sessions had 0 messages. Now:
  - No sessions at all → "no managed sessions found in {path}. Start
    claw to create a session..."
  - Sessions exist but all empty → "all sessions are empty (0 messages)
    in {path}. This usually means a fresh claw session is running but
    no messages have been sent yet. Wait for a response in your other
    session, then try --resume latest again."

- Add test for the all-sessions-empty error path.

  Addresses reviewer feedback on #3216.
This commit is contained in:
TheArchitectit
2026-06-03 13:44:20 -05:00
parent e459a727e9
commit 41034bb3f3
2 changed files with 72 additions and 8 deletions

View File

@ -199,6 +199,21 @@ impl SessionStore {
{
return Ok(latest);
}
// Distinguish between "no sessions at all" and "sessions exist but
// all are empty" so the user gets a clear signal about what to do.
let has_any_session = self
.list_sessions()?
.iter()
.any(|s| s.id != exclude)
|| self
.scan_global_sessions()?
.iter()
.any(|s| s.id != exclude);
if has_any_session {
return Err(SessionControlError::Format(
format_all_sessions_empty(&self.sessions_root),
));
}
Err(SessionControlError::Format(format_no_managed_sessions(
&self.sessions_root,
)))
@ -774,6 +789,16 @@ fn format_no_managed_sessions(sessions_root: &Path) -> String {
)
}
fn format_all_sessions_empty(sessions_root: &Path) -> String {
let fingerprint_dir = sessions_root
.file_name()
.and_then(|f| f.to_str())
.unwrap_or("<unknown>");
format!(
"all sessions are empty (0 messages) in .claw/sessions/{fingerprint_dir}/\nThis usually means a fresh `claw` session is running but no messages have been sent yet.\nWait for a response in your other session, then try `--resume {LATEST_SESSION_REFERENCE}` again."
)
}
fn format_legacy_session_missing_workspace_root(
session_path: &Path,
workspace_root: &Path,
@ -1229,6 +1254,35 @@ mod tests {
fs::remove_dir_all(base).expect("temp dir should clean up");
}
#[test]
fn latest_session_returns_all_empty_error_when_sessions_exist_but_have_no_messages() {
// given — create sessions with 0 messages (empty)
let base = temp_dir();
fs::create_dir_all(&base).expect("base dir should exist");
let store = SessionStore::from_cwd(&base).expect("store should build");
let empty_handle = store.create_handle("empty-session");
Session::new()
.with_persistence_path(empty_handle.path.clone())
.save_to_path(&empty_handle.path)
.expect("empty session should save");
// when — latest_session should fail with the "all sessions empty" message
let result = store.latest_session();
assert!(result.is_err(), "latest_session should fail when all sessions are empty");
let err_msg = result.unwrap_err().to_string();
assert!(
err_msg.contains("all sessions are empty"),
"error should mention 'all sessions are empty', got: {err_msg}"
);
assert!(
err_msg.contains("0 messages"),
"error should mention '0 messages', got: {err_msg}"
);
fs::remove_dir_all(base).expect("temp dir should clean up");
}
#[test]
fn session_exists_and_delete_are_scoped_to_workspace_store() {
// given

View File

@ -15377,16 +15377,26 @@ UU conflicted.rs",
std::env::set_current_dir(&workspace).expect("switch cwd");
let older = create_managed_session_handle("session-older").expect("older handle");
Session::new()
.with_persistence_path(older.path.clone())
.save_to_path(&older.path)
.expect("older session should save");
{
let mut session = Session::new().with_persistence_path(older.path.clone());
session
.push_user_text("older session message")
.expect("older message should save");
session
.save_to_path(&older.path)
.expect("older session should save");
}
std::thread::sleep(Duration::from_millis(20));
let newer = create_managed_session_handle("session-newer").expect("newer handle");
Session::new()
.with_persistence_path(newer.path.clone())
.save_to_path(&newer.path)
.expect("newer session should save");
{
let mut session = Session::new().with_persistence_path(newer.path.clone());
session
.push_user_text("newer session message")
.expect("newer message should save");
session
.save_to_path(&newer.path)
.expect("newer session should save");
}
let resolved = resolve_session_reference("latest").expect("latest session should resolve");
assert_eq!(