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

  1. Confirm the session id still exists (SELECT on chat_sessions) before retrying
  2. Check logs for '[ChatService] Failed to update session <id>: <cause>' to distinguish not-found from DB failure
  3. If it's a delete/update race, treat not-found as idempotent success instead of an error
  4. Fix DB connectivity if save() is the failing step
  5. 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

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


AI-assisted analysis of Crosstalk-Solutions/project-nomad@0bd1c6f4f9 (2026-08-27). Data as JSON: /api/errors/f38bbd1dfd8b4d12. Report an issue: GitHub.