-
Notifications
You must be signed in to change notification settings - Fork 6
Description
Description
JsonFileStorage::new in src/cortex-engine/src/memory/store/json_file.rs will panic/return an error when the backing file exists but is empty. This happens because serde_json::from_str("") returns an error for an empty string, unlike the SqliteStorage backend which correctly handles the empty-file case.
Affected File
src/cortex-engine/src/memory/store/json_file.rs, lines 25-39
pub async fn new(path: PathBuf) -> Result<Self> {
let memories = if path.exists() {
let content = tokio::fs::read_to_string(&path).await?;
let list: Vec<Memory> = serde_json::from_str(&content)?; // <-- crashes if content is empty string
list.into_iter().map(|m| (m.id, m)).collect()
} else {
HashMap::new()
};
...
}Root Cause
When a JSON memory file is created (e.g., by save() writing an empty []) and then the process is killed before writing, or when the file is created externally as empty, serde_json::from_str("") returns Err(EOF while parsing a value). This propagates as an error from JsonFileStorage::new, preventing the memory system from initializing.
Compare with SqliteStorage::new (lines 28-35) which correctly handles this:
let content = tokio::fs::read_to_string(&path).await.unwrap_or_default();
if content.is_empty() {
HashMap::new()
} else {
let list: Vec<Memory> = serde_json::from_str(&content).unwrap_or_default();
...
}Steps to Reproduce
- Create an empty file at the path used for
JsonFileStorage - Call
JsonFileStorage::new(path) - Observe error:
EOF while parsing a value at line 1 column 0
Expected Behavior
An empty file should be treated as an empty memory store (no memories), matching the behavior of SqliteStorage.
Actual Behavior
JsonFileStorage::new returns an error, preventing the memory system from initializing.
Fix
let content = tokio::fs::read_to_string(&path).await?;
let list: Vec<Memory> = if content.trim().is_empty() {
Vec::new()
} else {
serde_json::from_str(&content)?
};