moeru-ai/airi · error · Error
Invalid chat session export format
Error message
Invalid chat session export format
What it means
Thrown by importChatSessions in the data-maintenance composable when the parsed JSON fails isChatSessionsPayload: the top-level `format` field must be the exact string 'chat-sessions-index:v1', matching what chatStore.exportSessions() writes on export. It protects chatStore.importSessions from receiving arbitrary JSON before anything is written to the store. Any other structure — a hand-edited file, a different version's export, or unrelated JSON that happened to parse — is rejected.
Solutions
- Re-export chat sessions with the same app version's export button and import that file
- Open the JSON and confirm the top level contains the key format set to 'chat-sessions-index:v1'
- If migrating an older export, write a one-off converter that sets the v1 format key and the expected sessions structure
- Validate the file is complete, parseable JSON before import — truncated downloads fail the check
Example fix
// before
const payload = JSON.parse(await file.text())
await importChatSessions(payload) // throws: Invalid chat session export format
// after
const payload = JSON.parse(await file.text())
if (payload?.format !== 'chat-sessions-index:v1')
throw new Error('Selected file is not an AIRI chat export (expected chat-sessions-index:v1)')
await importChatSessions(payload) Defensive patterns
Strategy: type-guard
Validate before calling
const raw = JSON.parse(await file.text())
const isExport = !!raw && typeof raw === 'object' && raw.format === 'chat-sessions-index:v1'
if (!isExport)
throw new Error('Not a chat sessions export') Type guard
function isChatSessionsPayload(payload: unknown): payload is ChatSessionsExport {
return !!payload && typeof payload === 'object'
&& (payload as { format?: string }).format === 'chat-sessions-index:v1'
} Try / catch
try {
await importChatSessions(payload)
}
catch (err) {
// Distinguish format rejection from store failures so the UI tells the
// user to re-check the selected file instead of reporting a data bug.
toast(err instanceof Error && err.message === 'Invalid chat session export format'
? 'Selected file is not a chat session export'
: 'Import failed')
} Prevention
- Export and import with the same app version so format markers match
- Show the expected format string in the import UI next to the file picker
- Parse and format-check the file before calling importSessions
- Never hand-edit exports; write a converter that emits the exact v1 shape
When it happens
Trigger: Importing a file that was not produced by the matching export function: an older or newer app version's export carrying a different format marker, a manually authored file, a truncated download, or a single-session export instead of the full sessions index.
Common situations: User picks the wrong file in the import picker; migrating chats between machines running different app versions; editing the exported JSON by hand; importing an export produced by a different AIRI stage app whose store writes another format key.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- The file does not contain valid JSON.
- The file does not contain valid JSON.
- A motion sample occurs after the recording duration.
- Aliyun NLS credentials are incomplete.
- Archive entry not found
AI-assisted analysis of moeru-ai/airi@438a067dde (2026-08-18).
Data as JSON: /api/errors/564acd6f7ad23833.
Report an issue: GitHub.
Appendix: source
Thrown at packages/stage-ui/src/composables/use-data-maintenance.ts:99
function deleteAllChatSessions() {
chatOrchestrator.cancelPendingSends()
chatStore.resetAllSessions()
}
async function exportChatSessions() {
const data = await chatStore.exportSessions()
return new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' })
}
function isChatSessionsPayload(payload: unknown): payload is ChatSessionsExport {
if (!payload || typeof payload !== 'object')
return false
return (payload as { format?: string }).format === 'chat-sessions-index:v1'
}
async function importChatSessions(payload: Record<string, unknown>) {
if (!isChatSessionsPayload(payload))
throw new Error('Invalid chat session export format')
await chatStore.importSessions(payload)
return payload
}
async function resetSettingsState() {
await settingsStore.resetState()
audioSettingsStore.resetState()
live2dParamsStore.resetState()
live2dSettingsStore.resetState()
live2dMagicSettingsStore.resetState()
threeStore.resetModelStore()
mcpStore.resetState()
onboardingStore.resetSetupState()
airiCardStore.resetState()
}
async function deleteAllData() {
await deleteAllModels()View on GitHub (pinned to 438a067dde)