{"record":{"id":"f4b57c04814bd662","repo":"dgraph-io/badger","slug":"errdiscardedtxn","errorCode":"ErrDiscardedTxn","errorMessage":"This transaction has been discarded. Create a new one","messagePattern":"This transaction has been discarded\\. Create a new one","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"errors.go","lineNumber":37,"sourceCode":"\t// ErrValueLogSize is returned when opt.ValueLogFileSize option is not within the valid\n\t// range.\n\tErrValueLogSize = stderrors.New(\"Invalid ValueLogFileSize, must be in range [1MB, 2GB)\")\n\n\t// ErrKeyNotFound is returned when key isn't found on a txn.Get.\n\tErrKeyNotFound = stderrors.New(\"Key not found\")\n\n\t// ErrTxnTooBig is returned if too many writes are fit into a single transaction.\n\tErrTxnTooBig = stderrors.New(\"Txn is too big to fit into one request\")\n\n\t// ErrConflict is returned when a transaction conflicts with another transaction. This can\n\t// happen if the read rows had been updated concurrently by another transaction.\n\tErrConflict = stderrors.New(\"Transaction Conflict. Please retry\")\n\n\t// ErrReadOnlyTxn is returned if an update function is called on a read-only transaction.\n\tErrReadOnlyTxn = stderrors.New(\"No sets or deletes are allowed in a read-only transaction\")\n\n\t// ErrDiscardedTxn is returned if a previously discarded transaction is reused.\n\tErrDiscardedTxn = stderrors.New(\"This transaction has been discarded. Create a new one\")\n\n\t// ErrEmptyKey is returned if an empty key is passed on an update function.\n\tErrEmptyKey = stderrors.New(\"Key cannot be empty\")\n\n\t// ErrInvalidKey is returned if the key has a special !badger! prefix,\n\t// reserved for internal usage.\n\tErrInvalidKey = stderrors.New(\"Key is using a reserved !badger! prefix\")\n\n\t// ErrBannedKey is returned if the read/write key belongs to any banned namespace.\n\tErrBannedKey = stderrors.New(\"Key is using the banned prefix\")\n\n\t// ErrThresholdZero is returned if threshold is set to zero, and value log GC is called.\n\t// In such a case, GC can't be run.\n\tErrThresholdZero = stderrors.New(\n\t\t\"Value log GC can't run because threshold is set to zero\")\n\n\t// ErrNoRewrite is returned if a call for value log GC doesn't result in a log file rewrite.\n\tErrNoRewrite = stderrors.New(","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/dgraph-io/badger/blob/2a001d466f6b71a917319a1db41f99860e16e269/errors.go#L19-L55","documentation":"ErrDiscardedTxn indicates a previously discarded (or already committed) transaction is being reused. After txn.Discard() or Commit(), the txn is invalid; Badger returns this from setIdx/modify/Get, and NewIterator panics with it (iterator.go:461).","triggerScenarios":"Calling Get/Set/Delete/NewIterator after txn.Commit() or txn.Discard(); reusing a cached/stored transaction across requests; a deferred Discard executing before more operations; callbacks outliving the txn scope.","commonSituations":"Storing a Txn in a struct or pool and reusing it; forgetting that Commit implicitly discards; goroutines sharing a txn with mismatched lifetimes.","solutions":["Create a new transaction for each unit of work; never reuse after Commit/Discard","Remove transactions from caches/pools; keep txn lifetime inside one function scope","Do all operations before a deferred txn.Discard() runs","Check errors from Commit — a failed commit also ends the txn's usability"],"exampleFix":"// before\ntxn := db.NewTransaction(true)\ntxn.Commit()\nerr := txn.Set([]byte(\"k\"), []byte(\"v\")) // ErrDiscardedTxn\n// after\ntxn := db.NewTransaction(true)\nif err := txn.Set([]byte(\"k\"), []byte(\"v\")); err != nil { return err }\nreturn txn.Commit()","handlingStrategy":"validation","validationCode":"// track txn usability yourself; after Commit/Discard set used=true\nif txnDone {\n    return errors.New(\"transaction already committed or discarded\")\n}","typeGuard":null,"tryCatchPattern":"if err := txn.Get(k); err != nil {\n    if errors.Is(err, badger.ErrDiscardedTxn) {\n        txn = db.NewTransaction(true) // recreate and redo the operation\n    }\n    return err\n}","preventionTips":["Scope transactions to a single function; create-finish-discard locally","Never cache Txn objects in structs, pools, or globals","Remember Commit() also ends the txn — no ops afterwards"],"tags":["badger","transaction","lifecycle","api-misuse"],"backgroundTag":"stale-transaction-reuse","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"}