diff --git a/crates/chat-cli/src/cli/chat/context.rs b/crates/chat-cli/src/cli/chat/context.rs index 89edfb47aa..20dc3f654f 100644 --- a/crates/chat-cli/src/cli/chat/context.rs +++ b/crates/chat-cli/src/cli/chat/context.rs @@ -27,6 +27,19 @@ use crate::cli::chat::cli::hooks::HookExecutor; use crate::cli::chat::cli::model::ModelInfo; use crate::os::Os; +/// Custom serializer that filters out Session paths (which do not support serialization) and only +/// serializes Agent paths. +fn serialize_agent_paths_only(paths: &Vec, serializer: S) -> Result +where + S: Serializer, +{ + let agent_paths: Vec<&ContextFilePath> = paths + .iter() + .filter(|path| matches!(path, ContextFilePath::Agent(_))) + .collect(); + agent_paths.serialize(serializer) +} + #[derive(Debug, Clone)] pub enum ContextFilePath { /// Signifies that the path is brought in from the agent config @@ -97,6 +110,8 @@ pub struct ContextManager { /// Name of the current active profile. pub current_profile: String, /// List of file paths or glob patterns to include in the context. + /// Session paths are filtered out during serialization to prevent database persistence issues. + #[serde(serialize_with = "serialize_agent_paths_only")] pub paths: Vec, /// Map of Hook Name to [`Hook`]. The hook name serves as the hook's ID. pub hooks: HashMap>, @@ -457,4 +472,28 @@ mod tests { 96_000 ); } + + #[test] + fn test_context_manager_serialization_excludes_session_paths() -> Result<()> { + let mut manager = create_test_context_manager(None)?; + + // Add mixed agent and session paths to test filtering + manager.paths = vec![ + ContextFilePath::Agent("config_file.md".to_string()), + ContextFilePath::Session("temp_file.md".to_string()), + ]; + + // Serialization should succeed (no "Session paths are not serialized" error) + let serialized = serde_json::to_string(&manager)?; + + // Deserialize to verify structure + let deserialized: serde_json::Value = serde_json::from_str(&serialized)?; + + // Check that paths array only contains agent paths + let paths_array = deserialized["paths"].as_array().unwrap(); + assert_eq!(paths_array.len(), 1, "Should serialize only agent paths"); + assert_eq!(paths_array[0].as_str().unwrap(), "config_file.md"); + + Ok(()) + } } diff --git a/crates/chat-cli/src/cli/chat/conversation.rs b/crates/chat-cli/src/cli/chat/conversation.rs index 3d064c0180..da88c62dcb 100644 --- a/crates/chat-cli/src/cli/chat/conversation.rs +++ b/crates/chat-cli/src/cli/chat/conversation.rs @@ -402,7 +402,9 @@ impl ConversationState { }); if let Ok(cwd) = std::env::current_dir() { - os.database.set_conversation_by_path(cwd, self).ok(); + if let Err(e) = os.database.set_conversation_by_path(cwd, self) { + tracing::error!("Failed to save conversation to database: {}", e); + } } } diff --git a/crates/chat-cli/src/cli/chat/mod.rs b/crates/chat-cli/src/cli/chat/mod.rs index 53448af02d..b2f67c19a4 100644 --- a/crates/chat-cli/src/cli/chat/mod.rs +++ b/crates/chat-cli/src/cli/chat/mod.rs @@ -670,8 +670,15 @@ impl ChatSession { let mut existing_conversation = false; let previous_conversation = std::env::current_dir() .ok() - .and_then(|cwd| os.database.get_conversation_by_path(cwd).ok()) - .flatten(); + .and_then(|cwd| { + match os.database.get_conversation_by_path(cwd) { + Ok(conv) => conv, + Err(e) => { + tracing::warn!("Failed to load conversation from database: {}", e); + None + } + } + }); // Only restore conversations where there were actual messages. // Prevents edge case where user clears conversation then exits without chatting. diff --git a/crates/chat-cli/src/cli/mod.rs b/crates/chat-cli/src/cli/mod.rs index 1e384cf63e..18dc42a606 100644 --- a/crates/chat-cli/src/cli/mod.rs +++ b/crates/chat-cli/src/cli/mod.rs @@ -146,7 +146,9 @@ impl RootSubcommand { // Daily heartbeat check if os.database.should_send_heartbeat() && os.telemetry.send_daily_heartbeat().is_ok() { - os.database.record_heartbeat_sent().ok(); + if let Err(e) = os.database.record_heartbeat_sent() { + tracing::warn!("Failed to record heartbeat in database: {}", e); + } } // Send executed telemetry. diff --git a/crates/chat-cli/src/telemetry/cognito.rs b/crates/chat-cli/src/telemetry/cognito.rs index 4c541f508d..075ff39ea1 100644 --- a/crates/chat-cli/src/telemetry/cognito.rs +++ b/crates/chat-cli/src/telemetry/cognito.rs @@ -55,7 +55,9 @@ pub async fn get_cognito_credentials_send( "no credentials from get_credentials_for_identity", ))?; - database.set_credentials_entry(&credentials).ok(); + if let Err(e) = database.set_credentials_entry(&credentials) { + tracing::warn!("Failed to save credentials to database: {}", e); + } let Some(access_key_id) = credentials.access_key_id else { return Err(CredentialsError::provider_error("access key id not found"));