{"record":{"id":"89892486a515e051","repo":"dgraph-io/badger","slug":"base-level-can-t-be-zero","errorCode":null,"errorMessage":"Base level can't be zero.","messagePattern":"Base level can't be zero\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"levels.go","lineNumber":1256,"sourceCode":"\tcd.thisRange = infRange\n\tcd.top = out\n\n\t// Avoid any other L0 -> Lbase from happening, while this is going on.\n\tthisLevel := s.cstatus.levels[cd.thisLevel.level]\n\tthisLevel.ranges = append(thisLevel.ranges, infRange)\n\tfor _, t := range out {\n\t\ts.cstatus.tables[t.ID()] = struct{}{}\n\t}\n\n\t// For L0->L0 compaction, we set the target file size to max, so the output is always one file.\n\t// This significantly decreases the L0 table stalls and improves the performance.\n\tcd.t.fileSz[0] = math.MaxUint32\n\treturn true\n}\n\nfunc (s *levelsController) fillTablesL0ToLbase(cd *compactDef) bool {\n\tif cd.nextLevel.level == 0 {\n\t\tpanic(\"Base level can't be zero.\")\n\t}\n\t// We keep cd.p.adjusted > 0.0 here to allow functions in db.go to artificially trigger\n\t// L0->Lbase compactions. Those functions wouldn't be setting the adjusted score.\n\tif cd.p.adjusted > 0.0 && cd.p.adjusted < 1.0 {\n\t\t// Do not compact to Lbase if adjusted score is less than 1.0.\n\t\treturn false\n\t}\n\tcd.lockLevels()\n\tdefer cd.unlockLevels()\n\n\ttop := cd.thisLevel.tables\n\tif len(top) == 0 {\n\t\treturn false\n\t}\n\n\tvar out []*table.Table\n\tif len(cd.dropPrefixes) > 0 {\n\t\t// Use all tables if drop prefix is set. We don't want to compact only a","sourceCodeStart":1238,"sourceCodeEnd":1274,"githubUrl":"https://github.com/dgraph-io/badger/blob/2a001d466f6b71a917319a1db41f99860e16e269/levels.go#L1238-L1274","documentation":"fillTablesL0ToLbase panics if the compaction's next level is 0; L0->Lbase compaction must target a base level above 0. Reaching this panic indicates an internal invariant violation in level-controller state (baseLevel computation went wrong), often due to corrupted options or manifest state.","triggerScenarios":"Internal compaction scheduling computing nextLevel == 0 for an L0 compaction; induced compactions (like doCompact with a hand-made compactionPriority) where baseLevel wasn't set; MaxLevels/level-target options resulting in a zero base level.","commonSituations":"Custom code calling db.lc.doCompact or starting compactions with malformed compactionPriority; corrupted level-controller state after option changes (e.g. NumLevelZeroTables thresholds, MaxLevels).","solutions":["Do not call internal doCompact/fillTablesL0ToLbase directly with hand-built compactionPriority structs","Verify MaxLevels and level size options are sane so baseLevel > 0 is computed","Update badger to a version with the level-controller fixes if the panic occurs during normal operation"],"exampleFix":"// before\ndb.lc.doCompact(173, compactionPriority{level: 0, score: 1.73}) // baseLevel unset -> 0 -> panic\n// after\ndb.lc.doCompact(173, compactionPriority{level: 0, score: 1.73, t: db.lc.levelTargets(), baseLevel: 1}) // ensure baseLevel >= 1","handlingStrategy":"fallback","validationCode":"// Go: only trigger compactions through public APIs\n// use db.RunValueLogGC / automatic compaction instead of db.lc.doCompact(...)","typeGuard":null,"tryCatchPattern":"// Go\nfunc triggerCompact(db *badger.DB) (err error) {\n    defer func() { if r := recover(); r != nil { err = fmt.Errorf(\"compaction panic: %v\", r) } }()\n    return db.Flatten(2) // safe public alternative\n}","preventionTips":["Do not call internal levelsController methods with hand-built compactionPriority","Let automatic compaction schedule work; use db.Flatten for manual compaction","Keep level options (MaxLevels, baseLevelSize, size ratios) consistent","Upgrade badger if this panic occurs during normal operation"],"tags":["panic","compaction","internal-invariant"],"backgroundTag":"base-level-zero","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"}