{"record":{"id":"87a428aa8933f25e","repo":"dgraph-io/badger","slug":"throttle-do-done-mismatch","errorCode":null,"errorMessage":"Throttle Do Done mismatch","messagePattern":"Throttle Do Done mismatch","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"y/y.go","lineNumber":229,"sourceCode":"\t\t\treturn nil\n\t\tcase err := <-t.errCh:\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Done should be called by workers when they finish working. They can also\n// pass the error status of work done.\nfunc (t *Throttle) Done(err error) {\n\tif err != nil {\n\t\tt.errCh <- err\n\t}\n\tselect {\n\tcase <-t.ch:\n\tdefault:\n\t\tpanic(\"Throttle Do Done mismatch\")\n\t}\n\tt.wg.Done()\n}\n\n// Finish waits until all workers have finished working. It would return any error passed by Done.\n// If Finish is called multiple time, it will wait for workers to finish only once(first time).\n// From next calls, it will return same error as found on first call.\nfunc (t *Throttle) Finish() error {\n\tt.once.Do(func() {\n\t\tt.wg.Wait()\n\t\tclose(t.ch)\n\t\tclose(t.errCh)\n\t\tfor err := range t.errCh {\n\t\t\tif err != nil {\n\t\t\t\tt.finishErr = err\n\t\t\t\treturn\n\t\t\t}\n\t\t}","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/dgraph-io/badger/blob/2a001d466f6b71a917319a1db41f99860e16e269/y/y.go#L211-L247","documentation":"This is a panic raised inside Throttle.Done (y/y.go) when the internal channel is empty at Done time. Throttle pairs each Do() call with exactly one Done(); the select-with-default detects that Done was invoked more times than outstanding Do calls — an API-misuse bug in the worker goroutine (extra Done, or Done called outside the throttle's lifecycle). Since it is a panic, not an error return, it crashes the goroutine and typically the process; there is no recovery path inside Badger.","triggerScenarios":"Thrown at y/y.go:229 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Audit the code calling Throttle.Done: every call site must correspond to exactly one successful Throttle.Do on the same instance","Ensure error paths do not call Done twice (e.g. once in the worker and once in a deferred cleanup)","Wrap critical goroutines with recover if third-party code misuses the throttle, and log the stack to find the extra Done","Add unit tests that pair Do/Done under error conditions to prevent regression"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}