{"record":{"id":"4ff16b56fb666670","repo":"AdguardTeam/AdGuardHome","slug":"encoding-unit-w","errorCode":null,"errorMessage":"encoding unit: %w","messagePattern":"encoding unit: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/stats/unit.go","lineNumber":354,"sourceCode":"\t\taddr := s.Address\n\t\tu.upstreamsResponses[addr]++\n\t\tu.upstreamsTimeSum[addr] += uint64(s.QueryDuration.Microseconds())\n\t}\n}\n\n// flushUnitToDB puts udb to the database at id.\nfunc (s *StatsCtx) flushUnitToDB(udb *unitDB, tx *bbolt.Tx, id uint32) (err error) {\n\ts.logger.Debug(\"flushing unit\", \"id\", id, \"req_num\", udb.NTotal)\n\n\tbkt, err := tx.CreateBucketIfNotExists(idToUnitName(id))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"creating bucket: %w\", err)\n\t}\n\n\tbuf := &bytes.Buffer{}\n\terr = gob.NewEncoder(buf).Encode(udb)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"encoding unit: %w\", err)\n\t}\n\n\terr = bkt.Put([]byte{0}, buf.Bytes())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"putting unit to database: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc convertTopSlice(a []countPair) (m []map[string]uint64) {\n\tm = make([]map[string]uint64, 0, len(a))\n\tfor _, it := range a {\n\t\tm = append(m, map[string]uint64{it.Name: it.Count})\n\t}\n\n\treturn m\n}","sourceCodeStart":336,"sourceCodeEnd":372,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/stats/unit.go#L336-L372","documentation":"Encoding the unitDB with gob before storing it in bbolt failed; wrapped as 'encoding unit'.","triggerScenarios":"flushUnitToDB serializing a unitDB containing a type that gob cannot encode (unexported fields without GobEncode, unsupported map key types, channels/funcs) or a nil embedded value.","commonSituations":"Struct changes between versions making gob encoding fail; internal state corrupted by concurrent mutation without proper locking.","solutions":["Check for recent changes to unitDB types (new unsupported fields)","Ensure units are not mutated concurrently with flush","Upgrade to a version where the encoding matches stored data"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := s.Close(); err != nil { if strings.Contains(err.Error(), \"encoding\") { /* data shape issue; consider dropping stats DB */ } }","preventionTips":["Avoid mutating units concurrently with flush","Regenerate stats DB after version upgrades if schemas changed"],"tags":["stats","serialization","gob"],"backgroundTag":"serialization-failed","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}