{"record":{"id":"f1e1d6fff4ef1522","repo":"dgraph-io/badger","slug":"errnoroom","errorCode":"errNoRoom","errorMessage":"No room for write","messagePattern":"No room for write","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db.go","lineNumber":1040,"sourceCode":"// error occurs, it will be passed back via the callback.\n//\n//\terr := kv.BatchSetAsync(entries, func(err error)) {\n//\t   Check(err)\n//\t}\nfunc (db *DB) batchSetAsync(entries []*Entry, f func(error)) error {\n\treq, err := db.sendToWriteCh(entries)\n\tif err != nil {\n\t\treturn err\n\t}\n\tgo func() {\n\t\terr := req.Wait()\n\t\t// Write is complete. Let's call the callback function now.\n\t\tf(err)\n\t}()\n\treturn nil\n}\n\nvar errNoRoom = errors.New(\"No room for write\")\n\n// ensureRoomForWrite is always called serially. It blocks (without busy-polling)\n// until the current memtable can be flushed, i.e. until flushChan has room.\nfunc (db *DB) ensureRoomForWrite() error {\n\tvar err error\n\tdb.lock.Lock()\n\tdefer db.lock.Unlock()\n\n\ty.AssertTrue(db.mt != nil) // A nil mt indicates that DB is being closed.\n\tif !db.mt.isFull() {\n\t\treturn nil\n\t}\n\n\tfor {\n\t\tselect {\n\t\tcase db.flushChan <- db.mt:\n\t\t\tdb.opt.Debugf(\"Flushing memtable, mt.size=%d size of flushChan: %d\\n\",\n\t\t\t\tdb.mt.sl.MemSize(), len(db.flushChan))","sourceCodeStart":1022,"sourceCodeEnd":1058,"githubUrl":"https://github.com/dgraph-io/badger/blob/2a001d466f6b71a917319a1db41f99860e16e269/db.go#L1022-L1058","documentation":"errNoRoom (\"No room for write\") is returned by ensureRoomForWrite, which blocks until the memtable can be flushed to make room for an incoming write. It is returned to the caller when the DB is closed while a writer waits on flushCond, or when a write cannot proceed because there is no room.","triggerScenarios":"Calling db.Write/Commit concurrently with db.Close(); writeCallbacks loop sees IsClosed() while waiting; writes continuing after close started, or memtable flush backpressure with a closed/stalled flusher.","commonSituations":"App shutdown racing in-flight writes; not waiting for pending transactions before Close; flush pipeline stalled (disk full) combined with close.","solutions":["Ensure all writers finish before calling db.Close() (use a WaitGroup)","Retry writes that return errNoRoom after checking db.IsClosed()","Check disk space/health if it appears while the DB is still open"],"exampleFix":"// before\ngo func(){ txn.Commit() }()\ndb.Close() // writer may get errNoRoom\n// after\nwg.Wait() // wait for all writers\ndb.Close()","handlingStrategy":"retry","validationCode":"if db.IsClosed() { return errors.New(\"db closed; not writing\") }","typeGuard":null,"tryCatchPattern":"for {\n    err := db.Write(ctx, entries)\n    if err == nil { break }\n    if errors.Is(err, badger.ErrNoRoom) || err.Error() == \"No room for write\" {\n        if db.IsClosed() { return err }\n        time.Sleep(50 * time.Millisecond); continue\n    }\n    return err\n}","preventionTips":["Join all writers (WaitGroup) before db.Close()","Don't submit writes from goroutines outliving the DB","Monitor disk space; a stalled flusher worsens backpressure"],"tags":["badger","write","backpressure","closed"],"backgroundTag":"no-room-for-write","analyzedSha":"2a001d466f6b71a917319a1db41f99860e16e269","analyzedAt":"2026-09-05T13:00:02.264Z","contentChangedAt":"2026-09-05T13:00:02.264Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}