Skip to main content
One unreadable chat is reported, never allowed to truncate the list behind it.

Quick Start

1

Load the readable chats

list() returns every chat it could read, newest first. A single corrupt file drops out silently here — it does not truncate the list.
2

Report the unreadable ones

listUnreadable() returns the ids of every corrupt file, so the app can name an accurate count instead of losing conversations in silence.

How It Works

list() reads each id in isolation, so a failure on one file cannot stop the ones after it.
A future schemaVersion is refused as too_new, not truncated — reading a newer file with an older client and dropping the fields it does not understand would turn a version skew into data loss on the next write. too_new counts as unreadable for listUnreadable().

Chat list ordering

repo.list() returns chats newest-first by updated. The updated timestamp advances on every recorded turn — not only when the chat is first created — so the conversation the user is actively in stays at the top of the list.
A chat whose updated is pinned to its first message sinks to the bottom of the list the moment any other chat is touched. updated must be refreshed on every session.record(prompt, answer), or the “recently used” list stops being recently-used — an untouched month-old chat sits at the top while the one you are typing in drops out of sight.

User interaction flow

1

A crash corrupts one write

The user reopens the app after a crash truncated a chat mid-write. The conversation list still appears complete — every other chat is intact and ordered newest-first.
2

The app surfaces the count

listUnreadable() returns the one broken id, so the app shows a subtle recovery banner naming the count. No conversation vanishes without the user being told.

Best Practices

list() alone hides corrupt files by design. Call listUnreadable() on the same screen so a lost conversation is surfaced with a count rather than disappearing in silence.
A file that vanished between listIds() and read() is not corrupt — do not warn on it. Only ids returned by listUnreadable() are broken.
A chat missing its id is reported as unreadable, not loaded with id: undefined. Saving such a chat would write to chats/undefined and collide with every other id-less file.

Storage & Secrets

Where chats persist as opaque strings.

Errors & Recovery

What each failure looks like on the phone.