[Bug] Concurrent mcode processes kill each other's turns: SQLITE_BUSY on shared runtime-state.sqlite

Aperta
#282 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
45/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
sqlite, typescript
Ambito
backend, databases

Direzione di ricerca

Reproduce the failure with 5+ concurrent mcode sessions and inspect ~/.minimax/v2/observability/logs/runtime-*.log for the history-delivery or event-writer stage. Then trace the transaction helpers $t, YMe, and transaction(r).immediate() in the bundled chunks around runtime-state.sqlite. Done means concurrent turns no longer abort with SQLITE_BUSY or database-locked errors.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Summary

When several minimax-code processes run in parallel (common for power users running multiple sessions), turns intermittently die with:

The response failed.
Reason: database is locked

The failure is local, not an upstream API error — the request never reaches the network. From ~/.minimax/v2/observability/logs/runtime-*.log:

[pi-turn-runner] history delivery failed ... SqliteError: database is locked
    at sqliteTransaction (.../better-sqlite3/lib/methods/transaction.js:63:9)
[local-runtime-v2] agent host turn failed ... failure_stage="Agent execution failed."

Root cause

All processes share a single ~/.minimax/v2/sqlite/runtime-state.sqlite (WAL mode). The runtime sets PRAGMA busy_timeout = 5000, but under N concurrent writers a 5s wait is not always enough, and no retry on SQLITE_BUSY exists — the transaction wrapper ($t, YMe, and the goal-repo transaction(r).immediate() call sites in the bundled chunks) throws immediately once the timeout expires. The turn then fails at history delivery / event writer stage and the whole agent turn is aborted.

Observed with 9 concurrent processes on a ~330 MB database; frequency grows with parallelism and DB size.

Suggested fixes (any of)

  1. Retry with backoff on SQLITE_BUSY around the transaction helpers — cheapest, survives arbitrarily long foreign transactions.
  2. Raise busy_timeout (e.g. 30s) — helps but does not cover BUSY_SNAPSHOT cases.
  3. Shard session-scoped tables per session (e.g. runtime-state-<session>.sqlite) while keeping shared tables (local_runtime_agents, local_runtime_communication_messages, local_runtime_queues, local_runtime_crons, local_runtime_background_tasks, local_runtime_session_locks) in a coordinator DB — removes write contention entirely for the hot path. Note: a naive per-session split is not possible because the schema intentionally mixes session-scoped and cross-session coordination tables.

Environment

  • @minimax-ai/code 0.5.0 (npm), Linux x64, Node v24.18.0
  • Repro: run 5+ mcode sessions concurrently with active tool calls; within an hour at least one turn dies with database is locked.
Lingua principale
TypeScript
Stelle
1.3k
Fork
141
Merge medio
2h 26m
PR unite (30g)
65

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di MiniMax-AI/minimax-code

Tutte le issue di MiniMax-AI/minimax-code

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.