moeru-ai/airi · warning
[chat-sync] listChats failed; skipping reconcile this round:
Error message
[chat-sync] listChats failed; skipping reconcile this round:
What it means
Reconcile cannot start this round: mapper.listChats() rejected, so the whole local-vs-remote reconciliation is skipped via early return. Local sessions do not get cloud ids minted, remote chats are not adopted, and tombstones are not drained until the next round. Reconcile re-runs after every successful (re)connect, so divergence is temporary once connectivity recovers.
Source
Thrown at packages/stage-ui/src/stores/chat/session-store.ts:813
const myEpoch = reconcileEpoch
const isStaleEpoch = () => myEpoch !== reconcileEpoch
const reconcileTask = (async () => {
const currentUserId = getCurrentUserId()
if (currentUserId === 'local') {
console.info('[chat-sync] reconcile skipped: anonymous user')
return
}
console.info('[chat-sync] reconcile start', { userId: currentUserId, serverUrl: SERVER_URL })
const mapper = getCloudMapper()
let remoteChats
try {
remoteChats = await mapper.listChats()
}
catch (err) {
console.warn('[chat-sync] listChats failed; skipping reconcile this round:', errorMessageFrom(err))
return
}
if (isStaleEpoch())
return
console.info('[chat-sync] listChats →', remoteChats.length, 'remote chats')
// Snapshot local metas owned by this user. Anonymous-era sessions are
// not promoted to the cloud automatically — the user can re-open them
// after signing in and the server is unaware of them.
const localOwnedMetas = Object.values(sessionMetas.value).filter(meta => meta.userId === currentUserId)
const plan = reconcileLocalAndRemote(localOwnedMetas, remoteChats)
// Tombstones: drop adopt entries for chats the user already deleted.
// The server's soft-delete may not have committed yet (offline DELETE
// path), so we still need to remember "do not re-adopt this id".
const tombstones = await chatSessionsRepo.getTombstones(currentUserId)
if (isStaleEpoch())
returnView on GitHub (pinned to b6d0809ecb)
Solutions
- Check that the hosted backend stack (server/docker-compose.yaml) is running and SERVER_URL is correct
- Re-authenticate if the underlying status is 401/403
- Do nothing for transient outages — reconcile re-runs after every successful reconnect
- Inspect the network request for GET /api/v1/chats to confirm status code and CORS/proxy behavior
- Rely on the outbox to keep local changes queueing so a skipped round never loses data
Defensive patterns
Strategy: retry
Validate before calling
if (!currentUserId) return // source already skips reconcile for anonymous users
Try / catch
let remoteChats
try {
remoteChats = await mapper.listChats()
}
catch (err) {
console.warn('[chat-sync] listChats failed; skipping reconcile this round:', errorMessageFrom(err))
return // next successful (re)connect re-runs reconcile
}
if (isStaleEpoch()) return Prevention
- Health-check SERVER_URL at startup and show connection state in settings
- Refresh auth before reconcile when tokens are short-lived
- Keep reconcile idempotent so skipped rounds are harmless
- Rely on the outbox for local writes so skipped rounds never lose data
When it happens
Trigger: Reconcile round starting while the backend is unreachable; auth token expired (401 on GET /api/v1/chats); proxy/CORS misconfiguration blocking the list call; API app down or returning 5xx.
Common situations: Backend down for maintenance while the client keeps scheduling reconcile rounds; token refresh missing so 401 repeats; SERVER_URL pointing at an old deployment.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- [chat-ws] socket error:
- [chat-ws] ws error event:
- [chat-sync] DELETE /api/v1/chats failed for
- [chat-sync] pullMessages failed for
- Failed to download MediaPipe vision task asset for ${key} af
AI-assisted analysis of moeru-ai/airi@b6d0809ecb (2026-08-18).
Data as JSON: /api/errors/a937412121453822.
Report an issue: GitHub.