OtterMind/Chat2DB · error · BusinessException
ai.chat.history.deleteMessagesFailed
ai.chat.history.deleteMessagesFailed
Error message
ai.chat.history.deleteMessagesFailed
What it means
Thrown by AiChatHistoryServiceImpl when Files.deleteIfExists(msgFile) raises IOException while deleting a session's messages JSON file. Args are {msgFile, e.getMessage()}. It only attempts deletion after the session was confirmed owned and removed from the sessions list. The i18n key is defined; resolves to the raw code if absent.
Source
Thrown at chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/ai/AiChatHistoryServiceImpl.java:182
}
return all.subList(all.size() - maxMessages, all.size());
}
private synchronized void deleteSessionLocal(String sessionId, Long userId) {
List<AiChatSession> sessions = loadSessions(userId);
// Only delete the message file when the session was actually owned by
// this user; otherwise a caller could delete another user's file by id.
boolean removed = sessions.removeIf(s -> Objects.equals(s.getId(), sessionId));
persistSessions(userId, sessions);
if (!removed) {
return;
}
Path msgFile = messagesPath(sessionId);
try {
Files.deleteIfExists(msgFile);
} catch (IOException e) {
throw new BusinessException("ai.chat.history.deleteMessagesFailed", new Object[]{msgFile, e.getMessage()}, e);
}
}
private Path sessionsPath(Long userId) {
return baseDir.resolve("sessions-" + userId + ".json");
}
private Path messagesPath(String sessionId) {
return baseDir.resolve(sessionId + ".json");
}
private List<AiChatSession> loadSessions(Long userId) {
Path path = sessionsPath(userId);
if (!Files.exists(path)) {
return new ArrayList<>();
}
try {
SessionsFile file = objectMapper.readValue(path.toFile(), SessionsFile.class);View on GitHub (pinned to 5ee1e990e7)
Solutions
- Check filesystem permissions on <basePath>/ai-chat-history/ (ConfigUtils.getBasePath()/ai-chat-history) and ensure the process user owns it.
- Retry once after a short delay if a transient lock is likely (Windows AV), since deleteIfExists is idempotent.
- On a read-only volume, remount rw or relocate chat2db.base.path to a writable directory.
- Note the sessions list is already persisted without the session; orphaned <sessionId>.json can be swept on startup.
Example fix
// before: single attempt throws on transient lock
Files.deleteIfExists(msgFile);
// after: tolerate transient lock then mark for sweep
try {
Files.deleteIfExists(msgFile);
} catch (IOException e) {
orphanSweeper.mark(msgFile); // clean on next startup
log.warn("could not delete {} now, scheduled for sweep", msgFile);
} Defensive patterns
Strategy: try-catch
Validate before calling
Path dir = Paths.get(ConfigUtils.getBasePath(), "ai-chat-history");
if (!Files.isWritable(dir)) {
throw new IllegalStateException("ai-chat-history not writable: " + dir);
} Try / catch
try {
history.deleteSession(userId, sessionId);
} catch (BusinessException e) {
if ("ai.chat.history.deleteMessagesFailed".equals(e.getCode())) {
// session already removed from list; orphan file can be swept later
orphanSweeper.mark((Path) e.getArgs()[0]);
}
} Prevention
- Ensure the process user owns and can write/delete in the ai-chat-history dir.
- On Windows, exclude the data dir from AV locking.
- Implement a startup orphan-file sweeper for files that failed to delete.
When it happens
Trigger: Deleting a session whose <sessionId>.json message file cannot be removed: permission denied on the file, the file is locked by another process (antivirus/indexer on Windows), or the filesystem is read-only. The sessions list is already updated, so the session disappears but its message file lingers.
Common situations: Running on a read-only or permission-restricted storage mount; an antivirus holding a lock on Windows; the ai-chat-history dir has wrong ownership; container volume mounted read-only.
Related errors
- ai.chat.history.persistSessionsFailed
- ai.chat.history.persistMessagesFailed
- ai.attachment.localParseFailed
- ai.chat.history.loadSessionsFailed
- ai.chat.history.loadMessagesFailed
AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14).
Data as JSON: /api/errors/672a546c79f5cf40.
Report an issue: GitHub.