Crosstalk-Solutions/project-nomad · error · Error
Failed to update chat session
Error message
Failed to update chat session
What it means
ChatService.updateSession rethrows this after logging when either ChatSession.findOrFail(sessionId) rejects (session not found) or the subsequent session.save() fails (DB error). findOrFail's ModelNotFoundException surfaces here as this generic message.
Source
Thrown at admin/app/services/chat_service.ts:182
if (data.model !== undefined) {
session.model = data.model
}
await session.save()
return {
id: session.id.toString(),
title: session.title,
model: session.model,
timestamp: session.updated_at.toJSDate(),
}
} catch (error) {
logger.error(
`[ChatService] Failed to update session ${sessionId}: ${
error instanceof Error ? error.message : error
}`
)
throw new Error('Failed to update chat session')
}
}
async addMessage(sessionId: number, role: 'system' | 'user' | 'assistant', content: string) {
try {
const message = await ChatMessage.create({
session_id: sessionId,
role,
content,
})
// Update session's updated_at timestamp
const session = await ChatSession.findOrFail(sessionId)
session.updated_at = DateTime.now()
await session.save()
return {
id: message.id.toString(),View on GitHub (pinned to 0bd1c6f4f9)
Solutions
- Confirm the session id still exists (SELECT on chat_sessions) before retrying
- Check logs for '[ChatService] Failed to update session <id>: <cause>' to distinguish not-found from DB failure
- If it's a delete/update race, treat not-found as idempotent success instead of an error
- Fix DB connectivity if save() is the failing step
- Pass { cause: error } through for diagnosability
Example fix
// before
} catch (error) {
throw new Error('Failed to update session')
}
// after
import { Exception } from '@adonisjs/core/exceptions'
try {
// ...
} catch (error) {
if (error.code === 'E_ROW_NOT_FOUND') return false // deleted concurrently — treat as no-op
throw new Error('Failed to update session', { cause: error })
} Defensive patterns
Strategy: try-catch
Validate before calling
const exists = await ChatSession.find(sessionId) if (!exists) return handleSessionGone() // avoid E_ROW_NOT_FOUND path
Type guard
async function sessionExists(id: number): Promise<boolean> {
return (await ChatSession.find(id)) !== null
} Try / catch
try { await chat.updateSession(id, patch) } catch (e) { if (e.message === 'Failed to update chat session') { refreshSessionList(); return } throw e } Prevention
- Check session existence before update in UI flows with stale data
- Make title-generation updates tolerant of deleted sessions (idempotent no-op)
- Distinguish E_ROW_NOT_FOUND from DB errors in the service layer
- Propagate cause for diagnosability
When it happens
Trigger: Calling updateSession with a sessionId that was already deleted, calling it after generateTitle with a stale id, or a DB failure during save() (connection dropped, constraint on the title/model column).
Common situations: Race where the user deletes a session in another tab while an LLM title-generation flow tries to update it, concurrent requests with stale session ids, or transient DB disconnects during long chat operations.
Related errors
- Failed to delete chat session
- Failed to create chat session
- Failed to add message
- Failed to delete all chat sessions
- No response from Ollama
AI-assisted analysis of Crosstalk-Solutions/project-nomad@0bd1c6f4f9 (2026-08-27).
Data as JSON: /api/errors/f38bbd1dfd8b4d12.
Report an issue: GitHub.