{"record":{"id":"e3cf9f624ed263ec","repo":"AdguardTeam/AdGuardHome","slug":"opening-transaction-w","errorCode":null,"errorMessage":"opening transaction: %w","messagePattern":"opening transaction: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/stats/stats.go","lineNumber":269,"sourceCode":"\tdefer func() {\n\t\tcerr := db.Close()\n\t\tif cerr == nil {\n\t\t\ts.logger.Debug(\"database closed\")\n\t\t}\n\n\t\terr = errors.WithDeferred(err, cerr)\n\t}()\n\n\t// NOTE:  This mutex, when combined with the database transaction, is\n\t// required to be locked first.\n\ts.currMu.RLock()\n\tdefer s.currMu.RUnlock()\n\n\tudb := s.curr.serialize()\n\n\ttx, err := db.Begin(true)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"opening transaction: %w\", err)\n\t}\n\tdefer func() { err = errors.WithDeferred(err, finishTxn(tx, err == nil)) }()\n\n\treturn s.flushUnitToDB(udb, tx, s.curr.id)\n}\n\n// Update implements the [Interface] interface for *StatsCtx.  e must not be\n// nil.\nfunc (s *StatsCtx) Update(e *Entry) {\n\ts.confMu.Lock()\n\tdefer s.confMu.Unlock()\n\n\tif !s.enabled || s.limit == 0 {\n\t\treturn\n\t}\n\n\terr := e.validate()\n\tif err != nil {","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/stats/stats.go#L251-L287","documentation":"StatsCtx.Close attempts to flush the current unit to the database and fails at db.Begin(true); the error is wrapped as 'opening transaction'.","triggerScenarios":"Calling Close when the bbolt database is already closed, locked by another process, or on a read-only/full disk at shutdown time.","commonSituations":"Double Close, closing while another goroutine holds a transaction, shutdown races, or the DB file deleted/permissions changed while running.","solutions":["Ensure Close is called exactly once (sync.Once or guard flag)","Avoid concurrent transactions with Close; serialize access","Check filesystem health/disk space before shutdown"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"var once sync.Once\nonce.Do(func() { closeErr = s.Close() })","preventionTips":["Guard Close with sync.Once","Stop writers before closing","Drain in-flight transactions at shutdown"],"tags":["stats","database","bbolt","shutdown"],"backgroundTag":"database-transaction-failed","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}