dgraph-io/badger · error
Update can only be used with managedDB=false.
Error message
Update can only be used with managedDB=false.
What it means
db.Update is the user-mode (non-managed) transaction helper. When the DB was opened with WithManagedTransactions(true), Badger requires managed APIs (NewTransactionAt/CommitAt) and deliberately panics if Update is called, since implicit commit semantics conflict with managed version control. The check happens before any transaction is created.
Source
Thrown at txn.go:811
if db.opt.managedTxns {
txn = db.NewTransactionAt(math.MaxUint64, false)
} else {
txn = db.NewTransaction(false)
}
defer txn.Discard()
return fn(txn)
}
// Update executes a function, creating and managing a read-write transaction
// for the user. Error returned by the function is relayed by the Update method.
// Update cannot be used with managed transactions.
func (db *DB) Update(fn func(txn *Txn) error) error {
if db.IsClosed() {
return ErrDBClosed
}
if db.opt.managedTxns {
panic("Update can only be used with managedDB=false.")
}
txn := db.NewTransaction(true)
defer txn.Discard()
if err := fn(txn); err != nil {
return err
}
return txn.Commit()
}
View on GitHub (pinned to 2a001d466f)
Solutions
- Replace db.Update with db.NewTransactionAt(readonly=false) + explicit txn.CommitAt(ts, cb)
- Or open a second DB instance without WithManagedTransactions for user-mode code
- Audit call sites (populateEntries, updateLease, etc.) and convert each Update to the managed pattern
Example fix
// before
db.Update(func(txn *Txn) error { return txn.Set(key, val) })
// after
txn := db.NewTransactionAt(writeTs, true)
if err := txn.Set(key, val); err != nil { txn.Discard(); return err }
return txn.CommitAt(writeTs, nil) Defensive patterns
Strategy: validation
Validate before calling
if db.Opt().managedTxns == false {
return db.Update(fn)
}
txn := db.NewTransactionAt(writeTs, true)
err := fn(txn)
if err == nil { err = txn.CommitAt(writeTs, nil) } else { txn.Discard() }
return err Prevention
- Track managed mode as a config flag and branch transaction helpers on it
- Write managed-mode wrappers (UpdateAt/ViewAt) so raw Update is never called
- Search codebase for db.Update/View after enabling WithManagedTransactions
When it happens
Trigger: Opening DB with WithManagedTransactions(true) and then calling db.Update(fn) (or db.View with the same pattern); caller of Update such as a helper like moveMoney or a subscription handler (updateLease) that assumes user mode.
Common situations: Enabling managed mode to control read/write timestamps (e.g. Dgraph integration, replica read streams) while leftover application code still uses Update/View helpers.
Related errors
- cannot use NewWriteBatch in managed mode. Use NewWriteBatchA
- Nil callback provided to CommitWith
- Cannot use NewTransactionAt with managedDB=false. Use NewTra
- cannot use NewWriteBatchAt with managedDB=false. Use NewWrit
- cannot use NewManagedWriteBatch with managedDB=false. Use Ne
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/60b34eabd1d3dc9c.
Report an issue: GitHub.