{"record":{"id":"46866c5aeae10f68","repo":"dgraph-io/badger","slug":"cannot-use-badger-in-disk-less-mode-with-dir-or-va","errorCode":null,"errorMessage":"Cannot use badger in Disk-less mode with Dir or ValueDir set","messagePattern":"Cannot use badger in Disk-less mode with Dir or ValueDir set","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db.go","lineNumber":152,"sourceCode":"\tblockCache *ristretto.Cache[[]byte, *table.Block]\n\tindexCache *ristretto.Cache[uint64, *fb.TableIndex]\n\tallocPool  *z.AllocatorPool\n}\n\nconst (\n\tkvWriteChCapacity = 1000\n)\n\nfunc checkAndSetOptions(opt *Options) error {\n\t// It's okay to have zero compactors which will disable all compactions but\n\t// we cannot have just one compactor otherwise we will end up with all data\n\t// on level 2.\n\tif opt.NumCompactors == 1 {\n\t\treturn errors.New(\"Cannot have 1 compactor. Need at least 2\")\n\t}\n\n\tif opt.InMemory && (opt.Dir != \"\" || opt.ValueDir != \"\") {\n\t\treturn errors.New(\"Cannot use badger in Disk-less mode with Dir or ValueDir set\")\n\t}\n\topt.maxBatchSize = (15 * opt.MemTableSize) / 100\n\topt.maxBatchCount = opt.maxBatchSize / int64(skl.MaxNodeSize)\n\n\t// This is the maximum value, vlogThreshold can have if dynamic thresholding is enabled.\n\topt.maxValueThreshold = math.Min(maxValueThreshold, float64(opt.maxBatchSize))\n\tif opt.VLogPercentile < 0.0 || opt.VLogPercentile > 1.0 {\n\t\treturn errors.New(\"vlogPercentile must be within range of 0.0-1.0\")\n\t}\n\n\t// We are limiting opt.ValueThreshold to maxValueThreshold for now.\n\tif opt.ValueThreshold > maxValueThreshold {\n\t\treturn fmt.Errorf(\"Invalid ValueThreshold, must be less or equal to %d\",\n\t\t\tmaxValueThreshold)\n\t}\n\n\t// If ValueThreshold is greater than opt.maxBatchSize, we won't be able to push any data using\n\t// the transaction APIs. Transaction batches entries into batches of size opt.maxBatchSize.","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/dgraph-io/badger/blob/2a001d466f6b71a917319a1db41f99860e16e269/db.go#L134-L170","documentation":"This error is raised by checkAndSetOptions (db.go:152) during badger.Open when InMemory is true but Dir or ValueDir is also set to a non-empty path. In-memory mode is disk-less by definition: any configured directory contradicts the option and would otherwise be ignored or misused, so Open rejects the combination eagerly. It is an ad-hoc errors.New string, not a sentinel.","triggerScenarios":"badger.Open with Options where InMemory=true and either Dir != \"\" or ValueDir != \"\" — commonly DefaultOptions(\"/some/path\").WithInMemory(true), because DefaultOptions(path) pre-fills Dir/ValueDir.","commonSituations":"Starting from DefaultOptions(dir) for a disk deployment and flipping on WithInMemory(true) to test, forgetting the leftover path; environment-driven config where dir is always populated but an in-memory toggle was added later; test fixtures sharing one options builder.","solutions":["When InMemory is true, build options with badger.DefaultOptions(\"\") so Dir and ValueDir stay empty.","Conditionally clear the directories: if inMemory, set Dir=\"\" and ValueDir=\"\" before Open.","Make the in-memory toggle and the directory setting mutually exclusive in your configuration layer, validated before constructing badger.Options.","If persistence is actually needed, remove WithInMemory(true) instead and keep the paths."],"exampleFix":"// before\nopts := badger.DefaultOptions(dir).WithInMemory(true) // fails: Disk-less mode with Dir set\n// after\nif inMemory {\n    opts = badger.DefaultOptions(\"\").WithInMemory(true)\n} else {\n    opts = badger.DefaultOptions(dir)\n}\ndb, err := badger.Open(opts)","handlingStrategy":"validation","validationCode":"if opts.InMemory && (opts.Dir != \"\" || opts.ValueDir != \"\") {\n    return errors.New(\"badger: InMemory mode requires empty Dir and ValueDir\")\n}\ndb, err := badger.Open(opts)","typeGuard":"func optionsConsistent(opt badger.Options) bool {\n    return !opt.InMemory || (opt.Dir == \"\" && opt.ValueDir == \"\")\n}","tryCatchPattern":"db, err := badger.Open(opts)\nif err != nil {\n    if strings.Contains(err.Error(), \"Disk-less mode\") {\n        return fmt.Errorf(\"badger config conflict: InMemory=true with Dir=%q ValueDir=%q\", opts.Dir, opts.ValueDir)\n    }\n    return err\n}","preventionTips":["Build in-memory options only from badger.DefaultOptions(\"\") so Dir/ValueDir stay empty.","Never call DefaultOptions(path).WithInMemory(true); the path silently conflicts with InMemory.","Make in-memory vs persistent a single mutually exclusive config choice resolved in one place.","Add a unit test that Opens a DB with production-derived options to catch option conflicts in CI."],"tags":["badger","configuration","in-memory","options-validation"],"backgroundTag":"conflicting-options","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"}