Skip to main content
Mibyan keeps every conversation in one SQLite file per profile, state.db, with two sidecar files SQLite manages itself: state.db-wal (the write-ahead log) and state.db-shm. Several Mibyan processes can share that file safely — the gateway, the Desktop app, the dashboard, cron, and CLI commands all write through SQLite’s own locking. One thing is not safe: rewriting the store while another process is writing to it. When that happens, the processes still holding the old copy of the log stop writing on purpose and every turn answers with a message like:
another Mibyan process still holds an old copy of the session database’s write-ahead log, so Mibyan stopped writing to keep the file safe …
This page is the guide that message links to. Nothing is lost when you see it; the refusal exists precisely so nothing gets lost.

The fix in three steps

  1. Quit every Mibyan process on that profile. Desktop app, gateway, dashboard, cron:
    then quit the Desktop app from its menu and stop any dashboard (mibyan dashboard --stop) or custom service you run. Restarting one of them is not enough — a single process left holding the old log keeps every new one refusing.
  2. Ask doctor who is still holding the log.
    While anything still holds the retired log, doctor prints each holder as PID N (command) with the same remedy, and skips its health probes and any --fix work so it cannot become another writer. Stop the listed processes and run it again until the line is gone.
  3. Start Mibyan again (one process first — the gateway or the Desktop app) and send your message once more. Your conversation resumes from where it stopped.

Do not

  • Do not run mibyan doctor --fix while the processes are running. Doctor refuses the checkpoint while it can see a process holding the retired log, but on a host where it cannot inspect processes the fix path is exactly the second writer that caused the problem.
  • Do not delete state.db-wal or state.db-shm. The log holds committed conversations that are not yet in state.db. Deleting it is the one action that turns a refusal into real data loss.
  • Do not copy state.db alone. The three files are one image. Use a snapshot (mibyan backup) or mibyan sessions recover, never cp state.db somewhere/.
  • Do not ask the agent to fix it. The agent’s own session is in the same store; it will hit the same refusal.

Maintenance commands refuse while someone is writing

mibyan sessions optimize, mibyan sessions optimize-storage and mibyan sessions prune rewrite the store (VACUUM, a full-text index rebuild, bulk deletes). Running one of them under a live gateway is how a fleet of agents ends up in the refusal above, so they now check first and refuse while another process holds the database:
--dry-run previews are never blocked. --force runs anyway — use it only when you know the listed processes are idle (a reader you started yourself, for example). The same check runs when you type sessions optimize in the Desktop console.

Files you may find beside state.db

When the three steps do not work

If every Mibyan process is stopped, mibyan doctor no longer lists a holder, and the gateway still refuses to write when you start it, the file itself may be damaged. Stop everything again and inspect without writing:
--inspect-only never modifies the file. If it reports the store as recoverable, follow the command it prints, or restore the newest snapshot from state-snapshots/. The mechanics behind all of this are in the developer guide: State DB recovery and Session storage.