benbjohnson/litestream · error
store required
Error message
store required
What it means
NewDirectoryMonitor requires a non-nil *litestream.Store to attach the monitored databases to. This error is returned when the store parameter is nil, because the monitor has nowhere to register newly discovered databases. Like the dbc check, it is a constructor guard against invalid arguments.
Source
Thrown at cmd/litestream/directory_watcher.go:52
mu sync.Mutex
dbs map[string]*litestream.DB
watchedDirs map[string]struct{}
// Only accessed from the run() goroutine, so no mutex is needed.
pendingEvents map[string]fsnotify.Op
debounceActive bool
wg sync.WaitGroup
}
// NewDirectoryMonitor returns a new monitor for directory-based replication.
func NewDirectoryMonitor(ctx context.Context, store *litestream.Store, dbc *DBConfig, existing []*litestream.DB) (*DirectoryMonitor, error) {
if dbc == nil {
return nil, errors.New("database config required")
}
if store == nil {
return nil, errors.New("store required")
}
dirPath, err := expand(dbc.Dir)
if err != nil {
return nil, err
}
if _, err := os.Stat(dirPath); err != nil {
return nil, err
}
watcher, err := fsnotify.NewWatcher()
if err != nil {
return nil, err
}
monitorCtx, cancel := context.WithCancel(ctx)
dm := &DirectoryMonitor{View on GitHub (pinned to 4ed7a308f6)
Solutions
- Create and open the *litestream.Store before calling NewDirectoryMonitor, and pass the resulting pointer.
- Check the error/return of the code that built the store — a nil store usually means an earlier failure was swallowed.
- If store creation failed, abort startup instead of continuing with a nil store.
Example fix
// before
store, err := litestream.NewStore(cfg) // err ignored
mon, err := NewDirectoryMonitor(ctx, store, dbc, existing)
// after
store, err := litestream.NewStore(cfg)
if err != nil {
return err
}
if err := store.Open(); err != nil {
return err
}
mon, err := NewDirectoryMonitor(ctx, store, dbc, existing) Defensive patterns
Strategy: type-guard
Validate before calling
if store == nil {
return errors.New("store must be created and opened before starting the directory monitor")
} Type guard
func storeReady(s *litestream.Store) bool { return s != nil } Try / catch
mon, err := litestream.NewDirectoryMonitor(ctx, store, dbc, existing)
if err != nil {
if err.Error() == "store required" {
return fmt.Errorf("store not initialized: %w", err)
}
return err
} Prevention
- Establish a fixed startup order: create store, open it, then create monitors.
- Propagate (don't swallow) the error from store creation so a nil store never flows onward.
- Add an assertion/log at startup when store is nil.
When it happens
Trigger: Calling litestream.NewDirectoryMonitor(ctx, nil, dbc, existing) — typically when Store initialization failed earlier or was skipped, and the nil store was still passed to the monitor constructor.
Common situations: Embedding litestream where NewStore/Open failed or returned nil and the error was ignored; starting the directory monitor before the store is created; refactoring that reordered store creation after monitor startup.
Related errors
- database config required
- snapshot interval must be greater than 0
- snapshot retention must be greater than 0
- compaction interval must be greater than 0
- sync interval must be greater than 0
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/f189020563cd56e2.
Report an issue: GitHub.