benbjohnson/litestream · error

database config #%d: 'pattern' is required when using 'dir'

Error message

database config #%d: 'pattern' is required when using 'dir'

What it means

Config validation requires that when a database entry specifies a `dir` (directory of databases to watch), it must also specify a `pattern` that selects which files in that directory are databases. A dir without a pattern gives litestream no way to identify candidate database files, so Validate rejects the entry.

Source

Thrown at cmd/litestream/main.go:515

		}
		if db.Path == "" && db.Dir == "" {
			return fmt.Errorf("database config #%d: must specify either 'path' or 'dir'", idx+1)
		}

		// Reject the same database path listed twice. The metadata directory is
		// derived from the path, so two entries would share it and race on the
		// same LTX temp files.
		if db.Path != "" {
			key := filepath.Clean(db.Path)
			if first, ok := seenPaths[key]; ok {
				return fmt.Errorf("database config #%d: duplicate path %q (already used by database config #%d); each database can be listed only once", idx+1, db.Path, first)
			}
			seenPaths[key] = idx + 1
		}

		// When using dir, pattern must be specified
		if db.Dir != "" && db.Pattern == "" {
			return fmt.Errorf("database config #%d: 'pattern' is required when using 'dir'", idx+1)
		}
		if db.Watch && db.Dir == "" {
			return fmt.Errorf("database config #%d: 'watch' can only be enabled with a directory", idx+1)
		}
		if db.MetaDir != nil && db.Dir == "" {
			return fmt.Errorf("database config #%d: 'meta-dir' can only be used with a directory", idx+1)
		}
		if db.MetaPath != nil && db.MetaDir != nil {
			return fmt.Errorf("database config #%d: cannot specify both 'meta-path' and 'meta-dir'", idx+1)
		}

		// Use path or dir for identifying the config in error messages
		dbIdentifier := db.Path
		if dbIdentifier == "" {
			dbIdentifier = db.Dir
		}

		if db.Snapshot.Interval != nil && *db.Snapshot.Interval <= 0 {

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Add a `pattern` to the database entry, e.g. `pattern: "*.db"`, alongside `dir:`.
  2. Verify the key is spelled exactly `pattern` (not `patterns` or `glob`) and is non-empty.
  3. If you actually meant a single database, use `path:` instead of `dir:`.
  4. Re-run the command with the corrected config to confirm validation passes.

Example fix

# before (litestream.yml)
dbs:
  - dir: /var/lib/dbs
# after
dbs:
  - dir: /var/lib/dbs
    pattern: "*.db"
Defensive patterns

Strategy: validation

Validate before calling

# fail fast before deploy
if yq -e '.dbs[] | select(has("dir") and (has("pattern") | not))' litestream.yml >/dev/null; then
  echo 'db entry with dir is missing pattern'; exit 1
fi

Try / catch

if err := cmd.Run(); err != nil {
    if strings.Contains(err.Error(), "'pattern' is required when using 'dir'") {
        log.Fatal("add pattern: \"*.db\" next to dir: in litestream.yml")
    }
    log.Fatal(err)
}

Prevention

When it happens

Trigger: A `dbs:` entry with `dir: /var/lib/dbs` but no `pattern:` key; configs converted from path-based entries where someone swapped `path:` for `dir:` without adding the pattern.

Common situations: Users adopting directory watching for many SQLite files forgetting the glob pattern; copy-pasting dir-based examples from docs that show pattern in a later snippet; hand-written configs where the pattern key is misspelled (e.g. `patterns:`), leaving `pattern` effectively empty.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/d00c2d0c9589b625. Report an issue: GitHub.