charmbracelet/crush · error

failed to connect to database: %w

Error message

failed to connect to database: %w

What it means

After the data directory exists, CreateWorkspace opens the workspace SQLite database via db.Connect with a data-dir lock. Any connection failure (locked by another process, unreadable/corrupt DB file, unable to create the DB) is wrapped with this message.

Source

Thrown at internal/backend/backend.go:428

		}
	}()

	id := uuid.New().String()
	cfg, err := config.Init(args.Path, args.DataDir, args.Debug)
	if err != nil {
		return nil, proto.Workspace{}, fmt.Errorf("failed to initialize config: %w", err)
	}

	cfg.Overrides().SkipPermissionRequests = args.YOLO
	cfg.Overrides().EnabledChannels = args.Channels

	if err := createDotCrushDir(cfg.Config().Options.DataDirectory); err != nil {
		return nil, proto.Workspace{}, fmt.Errorf("failed to create data directory: %w", err)
	}

	conn, err := db.Connect(b.ctx, cfg.Config().Options.DataDirectory, db.WithDataDirLock(true))
	if err != nil {
		return nil, proto.Workspace{}, fmt.Errorf("failed to connect to database: %w", err)
	}

	// Discover skills once per workspace, before app.New. The backend
	// hosts multiple workspaces concurrently, so the manager is
	// constructed WITHOUT WithGlobalMirror to prevent last-writer-wins
	// cross-talk between workspaces.
	discoveryCfg := skillsDiscoveryConfig(cfg)
	allSkills, activeSkills, skillStates := skills.DiscoverFromConfig(discoveryCfg)
	skillsMgr := skills.NewManager(
		allSkills, activeSkills, skillStates,
		skills.WithResolvedPaths(discoveryCfg.ResolvePaths()),
		skills.WithWorkingDir(discoveryCfg.WorkingDir),
	)

	appWorkspace, err := app.New(b.ctx, conn, cfg, skillsMgr)
	if err != nil {
		return nil, proto.Workspace{}, fmt.Errorf("failed to create app workspace: %w", err)
	}

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Close other crush instances using the same data directory
  2. Remove a stale lock file / move the corrupt DB aside to re-initialize
  3. Move the data directory onto a local (non-NFS) filesystem

Example fix

// before
crush run  # database is locked
// after
pkill crush
rm ~/.crush/*.lock
crush run
Defensive patterns

Strategy: retry

Try / catch

ws, err := b.CreateWorkspace(ctx, args)
if err != nil && strings.Contains(err.Error(), "failed to connect to database") {
    time.Sleep(500 * time.Millisecond)
    ws, err = b.CreateWorkspace(ctx, args) // retry once; another instance may hold the lock
}
if err != nil {
    return err
}

Prevention

When it happens

Trigger: db.Connect fails: another crush instance holds the data-dir lock, the SQLite file is corrupt or unreadable, or the filesystem cannot create/write the database file.

Common situations: Two crush sessions sharing one data directory concurrently; stale lock after a crash; corrupt crush.db after disk issue; NFS/network filesystem that breaks SQLite locking.

Related errors


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