charmbracelet/crush · error

failed to connect to database: %w

Error message

failed to connect to database: %w

What it means

After config init, sessionSetup calls db.Connect to open (or create) the SQLite database in the data directory. Any connection failure is wrapped as this error and aborts the session subcommand. This is the DB availability gate for all session commands.

Source

Thrown at internal/cmd/session.go:124

func sessionSetup(cmd *cobra.Command) (context.Context, *sessionServices, func(), error) {
	dataDir, _ := cmd.Flags().GetString("data-dir")
	ctx := cmd.Context()

	cfg, err := config.Init("", dataDir, false)
	if err != nil {
		return nil, nil, nil, fmt.Errorf("failed to initialize config: %w", err)
	}
	if dataDir == "" {
		dataDir = cfg.Config().Options.DataDirectory
	}
	if shouldEnableMetrics(cfg.Config()) {
		event.Init()
	}

	conn, err := db.Connect(ctx, dataDir)
	if err != nil {
		return nil, nil, nil, fmt.Errorf("failed to connect to database: %w", err)
	}

	queries := db.New(conn)
	svc := &sessionServices{
		sessions: session.NewService(queries, conn),
		messages: message.NewService(queries),
		cfg:      cfg,
	}
	return ctx, svc, func() { conn.Close() }, nil
}

func runSessionList(cmd *cobra.Command, _ []string) error {
	event.SetNonInteractive(true)

	ctx, svc, cleanup, err := sessionSetup(cmd)
	if err != nil {
		return err
	}

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Verify the data directory exists and is writable (ls -ld, touch a test file)
  2. Check for stale SQLite lock/journal files (-wal, -shm) and that no other crush process is running
  3. If the DB is corrupted, back up and remove/recreate the database file in the data dir
  4. Check free disk space on the volume holding the data directory
Defensive patterns

Strategy: validation

Validate before calling

// ensure data dir is usable before connecting
if info, err := os.Stat(dataDir); err != nil || !info.IsDir() {
    if err := os.MkdirAll(dataDir, 0o755); err != nil {
        return fmt.Errorf("cannot create data dir: %w", err)
    }
}
probe := filepath.Join(dataDir, ".write-probe")
if err := os.WriteFile(probe, nil, 0o644); err != nil {
    return fmt.Errorf("data dir not writable: %w", err)
}
os.Remove(probe)

Try / catch

conn, err := db.Connect(ctx, dataDir)
if err != nil {
    slog.Error("Cannot open database", "dataDir", dataDir, "error", err)
    os.Exit(1)
}
defer conn.Close()

Prevention

When it happens

Trigger: db.Connect(ctx, dataDir) errors: data directory does not exist or is not writable, database file corrupted/locked, or the SQLite driver fails to initialize (CGO_ENABLED=0 modernc driver issue).

Common situations: Running with a --data-dir flag pointing at a non-existent or read-only path; another crush process holds a stale lock; disk full; database file corrupted after a crash.

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/6710545c485dcc3f. Report an issue: GitHub.