charmbracelet/crush · error

failed to gather stats: %w

Error message

failed to gather stats: %w

What it means

runStats wraps errors from gatherStats, which runs SQL aggregate queries against the connected database to compute token/cost/session statistics. This error means the stats queries themselves failed — typically a SQL error, a scan/row-conversion error, or a context cancellation mid-query — not that the connection is bad.

Source

Thrown at internal/cmd/stats.go:180

		}
		if dataDir == "" {
			dataDir = cfg.Config().Options.DataDirectory
		}
		if shouldEnableMetrics(cfg.Config()) {
			event.Init()
		}

		event.StatsViewed()

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

		stats, err := gatherStats(ctx, conn)
		if err != nil {
			return fmt.Errorf("failed to gather stats: %w", err)
		}

		projectStats = []ProjectStats{{ProjectPath: "", Stats: stats}}
	}

	if len(projectStats) == 0 {
		return fmt.Errorf("no data available: no projects found")
	}

	// Merge stats from all projects.
	mergedStats := mergeStats(projectStats)

	if mergedStats.Total.TotalSessions == 0 {
		return fmt.Errorf("no data available: no sessions found in database")
	}

	currentUser, err := user.Current()
	if err != nil {

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Read the wrapped cause in the error output and run `sqlite3 <dataDir>/crush.db 'PRAGMA integrity_check;'` to detect corruption.
  2. Ensure crush has run once normally so migrations applied (`crush` interactively) before running stats against the same data dir.
  3. Restore crush.db from backup if integrity check fails; alternatively back up and delete the db so a fresh one is created.
  4. Retry with an uninterrupted context (don't Ctrl-C during aggregation) on very large databases.
  5. Update crush to the latest version if the schema and query versions were mismatched.
Defensive patterns

Strategy: try-catch

Validate before calling

out, err := exec.Command("sqlite3", filepath.Join(dataDir, "crush.db"), "PRAGMA integrity_check;").Output()
if err != nil || !strings.Contains(string(out), "ok") {
	return fmt.Errorf("database integrity check failed")
}

Try / catch

stats, err := gatherStats(ctx, conn)
if err != nil {
	if errors.Is(err, context.Canceled) {
		return fmt.Errorf("stats query cancelled")
	}
	return fmt.Errorf("failed to gather stats: %w", err)
}

Prevention

When it happens

Trigger: `crush stats` with a database whose schema predates current migrations (missing columns/tables queried by gatherStats), a corrupted SQLite file returning I/O or database-disk-image errors mid-query, a cancelled context (Ctrl-C) during long aggregate queries, or NULL/type-mismatched rows that fail sql.Scan into int64/float64 fields.

Common situations: Upgrading crush and running stats against an old database if migrations partially failed; a crush.db damaged by a prior WAL desync (SQLITE_NOTADB/11 disk I/O error); very large databases where the query outlives a cancelled context; hand-edited or third-party-modified databases with unexpected row types.

Related errors


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