musistudio/claude-code-router · warning
[backend:${ownerId}] SQLite store close failed: ${formatErro
Error message
[backend:${ownerId}] SQLite store close failed: ${formatError(error)} What it means
Emitted by BackendService.stopOwner when closing one of an owner's SQLite stores throws. Each store owned by the plugin/owner being stopped is closed in a loop; a throw from store.close() (e.g. an unclosed prepared statement, busy database, or I/O error during checkpoint) is caught per-store, logged, and shutdown continues for the remaining stores. Shutdown never aborts because of it.
Source
Thrown at packages/core/src/plugins/backend-service.ts:124
if (options.migrate) {
await options.migrate(database);
store.persist();
}
return store;
}
async stopOwner(ownerId: string): Promise<void> {
const backends = this.backends.filter((backend) => backend.ownerId === ownerId);
this.backends = this.backends.filter((backend) => backend.ownerId !== ownerId);
await Promise.all(backends.map((backend) => closeServer(backend.server)));
const sqliteStores = this.sqliteStores.filter((store) => store.ownerId === ownerId);
this.sqliteStores = this.sqliteStores.filter((store) => store.ownerId !== ownerId);
for (const store of sqliteStores) {
try {
store.close();
} catch (error) {
console.warn(`[backend:${ownerId}] SQLite store close failed: ${formatError(error)}`);
}
}
}
async stopAll(): Promise<void> {
const ownerIds = new Set([
...this.backends.map((backend) => backend.ownerId),
...this.sqliteStores.map((store) => store.ownerId)
]);
await Promise.all([...ownerIds].map((ownerId) => this.stopOwner(ownerId)));
}
}
class SqliteStoreImpl implements SqliteStore {
constructor(
readonly ownerId: string,
readonly dbFile: string,
readonly database: SqlDatabaseView on GitHub (pinned to 99f24806c6)
Solutions
- Free disk space and verify write permissions on the SQLite state directory.
- Ensure no other process opens the same SQLite files (single-owner access).
- If it happens on every shutdown after a crash, stop everything, delete/recreate the affected store file (data loss limited to that store), and restart.
- Upgrade the core package — newer SQLite drivers checkpoint more gracefully on close.
Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
null
Prevention
- Ensure single-owner access to SQLite state files
- Free disk space before shutdown-heavy operations
- Treat per-store close warnings as non-fatal but investigate repeats
When it happens
Trigger: Calling stopAll, stop, rollbackConfiguredPluginLoad, or stopBrowserWebSearchMcpServers while a SQLite database file is locked, on a read-only/full disk, or when the store has open cursors/statements that make close() throw.
Common situations: Disk full or permissions changed under the state directory; another process (or an in-flight query) holds the SQLite file; plugin rollback racing with active writes during a config reload.
Related errors
- [plugin] Stop hook failed: ${formatError(error)}
- database disk image is malformed: integrity_check returned $
- project_id and path are required to write a Claude Design fi
- [plugin-marketplace] Failed to fetch marketplace from ${url}
- [plugin-marketplace] Failed to load marketplace entry: ${for
AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27).
Data as JSON: /api/errors/8ecaf4ee58f53594.
Report an issue: GitHub.