diff --git a/frontend-modern/src/components/Settings/AISettings.tsx b/frontend-modern/src/components/Settings/AISettings.tsx index abf05fb90..f87d4b4c5 100644 --- a/frontend-modern/src/components/Settings/AISettings.tsx +++ b/frontend-modern/src/components/Settings/AISettings.tsx @@ -12,6 +12,7 @@ import { AIAPI } from '@/api/ai'; import { AIChatAPI, type ChatSession, type FileChange } from '@/api/aiChat'; import { hasFeature, loadLicenseStatus } from '@/stores/license'; import type { AISettings as AISettingsType, AIProvider, AuthMethod } from '@/types/ai'; +import { normalizeChatSessions } from '@/components/Settings/aiSettingsChatSessions'; // Providers are now configured via accordion sections, not a single-provider selector @@ -284,10 +285,10 @@ export const AISettings: Component = () => { setChatSessionsLoading(true); setChatSessionsError(''); try { - const sessions = await AIChatAPI.listSessions(); + const sessions = normalizeChatSessions(await AIChatAPI.listSessions()); setChatSessions(sessions); const current = selectedSessionId(); - if (!Array.isArray(sessions) || sessions.length === 0) { + if (sessions.length === 0) { setSelectedSessionId(''); } else if (!current || !sessions.some((session) => session.id === current)) { setSelectedSessionId(sessions[0].id); diff --git a/frontend-modern/src/components/Settings/__tests__/aiSettingsChatSessions.test.ts b/frontend-modern/src/components/Settings/__tests__/aiSettingsChatSessions.test.ts new file mode 100644 index 000000000..80d03759c --- /dev/null +++ b/frontend-modern/src/components/Settings/__tests__/aiSettingsChatSessions.test.ts @@ -0,0 +1,21 @@ +import { describe, expect, it } from 'vitest'; + +import { normalizeChatSessions } from '@/components/Settings/aiSettingsChatSessions'; + +describe('normalizeChatSessions', () => { + it('returns the original array when the API payload is valid', () => { + const sessions = [ + { id: 'session-1', title: 'First', message_count: 1, updated_at: '2026-03-25T10:00:00Z' }, + ]; + + expect(normalizeChatSessions(sessions)).toEqual(sessions); + }); + + it('returns an empty array when the API payload is null', () => { + expect(normalizeChatSessions(null)).toEqual([]); + }); + + it('returns an empty array when the API payload is not an array', () => { + expect(normalizeChatSessions({ id: 'session-1' })).toEqual([]); + }); +}); diff --git a/frontend-modern/src/components/Settings/aiSettingsChatSessions.ts b/frontend-modern/src/components/Settings/aiSettingsChatSessions.ts new file mode 100644 index 000000000..58858b5d6 --- /dev/null +++ b/frontend-modern/src/components/Settings/aiSettingsChatSessions.ts @@ -0,0 +1,5 @@ +import type { ChatSession } from '@/api/aiChat'; + +export function normalizeChatSessions(value: unknown): ChatSession[] { + return Array.isArray(value) ? value : []; +}