dgraph-io/badger · error
Nil callback provided to CommitWith
Error message
Nil callback provided to CommitWith
What it means
CommitWith requires a callback because the commit result is delivered asynchronously via a goroutine. If you pass nil, Badger panics immediately at the public API boundary so the problem is caught before any commit work starts. Use Commit instead if you don't need a callback.
Source
Thrown at txn.go:702
case cb.user == nil:
panic("Must have caught a nil callback for txn.CommitWith")
case cb.err != nil:
cb.user(cb.err)
case cb.commit != nil:
err := cb.commit()
cb.user(err)
default:
cb.user(nil)
}
}
// CommitWith acts like Commit, but takes a callback, which gets run via a
// goroutine to avoid blocking this function. The callback is guaranteed to run,
// so it is safe to increment sync.WaitGroup before calling CommitWith, and
// decrementing it in the callback; to block until all callbacks are run.
func (txn *Txn) CommitWith(cb func(error)) {
if cb == nil {
panic("Nil callback provided to CommitWith")
}
if len(txn.pendingWrites) == 0 {
// Do not run these callbacks from here, because the CommitWith and the
// callback might be acquiring the same locks. Instead run the callback
// from another goroutine.
go runTxnCallback(&txnCb{user: cb, err: nil})
// Discard the transaction so that the read is marked done.
txn.Discard()
return
}
// Precheck before discarding txn.
if err := txn.commitPrecheck(); err != nil {
cb(err)
return
}
View on GitHub (pinned to 2a001d466f)
Solutions
- Pass a real callback: txn.CommitWith(func(err error){ ... })
- If no callback is needed, call txn.Commit() instead
- Guard wrappers: if cb == nil { return txn.Commit() }; txn.CommitWith(cb)
Example fix
// before
txn.CommitWith(nil)
// after
txn.CommitWith(func(err error) {
if err != nil { log.Printf("commit failed: %v", err) }
}) Defensive patterns
Strategy: validation
Validate before calling
if cb == nil { return errors.New("callback required; use txn.Commit() if none needed") }
txn.CommitWith(cb) Try / catch
defer func(){ if r := recover(); r != nil { if s, ok := r.(string); ok && strings.Contains(s, "Nil callback") { log.Error(s) } } }() Prevention
- Default to txn.Commit() when no async handling is needed
- Never forward nil callbacks through generic wrappers
- Initialize callback variables with a no-op func rather than leaving them nil
When it happens
Trigger: Calling txn.CommitWith(nil), or passing a variable holding a nil func(error) (including a typed-nil function value).
Common situations: Conditional callback assignment where the variable ends up nil; refactoring from Commit to CommitWith and forgetting to supply the callback; generic wrapper code that forwards a nil cb.
Related errors
- Must have caught a nil callback for txn.CommitWith
- Update can only be used with managedDB=false.
- Cannot use CommitAt with managedDB=false. Use Commit instead
- BlockCacheSize should be set since compression/encryption ar
- Cannot use GetSequence with managedDB=true.
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/b66ee48e324822f2.
Report an issue: GitHub.