charmbracelet/crush · error

get usage by model: %w

Error message

get usage by model: %w

What it means

gatherStats aggregates token/message usage per model via queries.GetUsageByModel and wraps any failure with this message. It signals the model-usage SQL query could not run against the session database.

Source

Thrown at internal/cmd/stats.go:581

		return nil, fmt.Errorf("get usage by day: %w", err)
	}
	for _, d := range dailyUsage {
		prompt := nullFloat64ToInt64(d.PromptTokens)
		completion := nullFloat64ToInt64(d.CompletionTokens)
		stats.UsageByDay = append(stats.UsageByDay, DailyUsage{
			Day:              fmt.Sprintf("%v", d.Day),
			PromptTokens:     prompt,
			CompletionTokens: completion,
			TotalTokens:      prompt + completion,
			Cost:             d.Cost.Float64,
			SessionCount:     d.SessionCount,
		})
	}

	// Usage by model.
	modelUsage, err := queries.GetUsageByModel(ctx)
	if err != nil {
		return nil, fmt.Errorf("get usage by model: %w", err)
	}
	for _, m := range modelUsage {
		stats.UsageByModel = append(stats.UsageByModel, ModelUsage{
			Model:        m.Model,
			Provider:     m.Provider,
			MessageCount: m.MessageCount,
		})
	}

	// Usage by hour.
	hourlyUsage, err := queries.GetUsageByHour(ctx)
	if err != nil {
		return nil, fmt.Errorf("get usage by hour: %w", err)
	}
	for _, h := range hourlyUsage {
		stats.UsageByHour = append(stats.UsageByHour, HourlyUsage{
			Hour:         int(h.Hour),
			SessionCount: h.SessionCount,

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Close other crush processes and rerun `crush stats`
  2. Check file permissions on the data dir/DB and fix with chown/chmod
  3. Validate the DB with `PRAGMA integrity_check` and restore or regenerate if corrupt
  4. Align the crush binary version with the database schema (reinstall the expected version)

Example fix

// before
sudo crush stats  # creates root-owned DB access issues
// after
chown -R $USER .crush && crush stats  # run as the owning user, not via sudo
Defensive patterns

Strategy: retry

Validate before calling

db="${CRUSH_DATA_DIR:-.crush}/crush.db"
[ -O "$db" ] || { echo "You do not own $db (run chown $USER)" >&2; exit 1; }
pgrep -f crush >/dev/null && { echo "Another crush process may hold the DB lock" >&2; exit 1; }

Try / catch

if err := gatherStats(ctx, dbPath); err != nil {
    if strings.Contains(err.Error(), "get usage by model") && strings.Contains(err.Error(), "locked") {
        // wait for the writer and retry
        time.Sleep(2 * time.Second)
        return gatherStats(ctx, dbPath)
    }
    return err
}

Prevention

When it happens

Trigger: GetUsageByModel fails: SQLite DB locked by another process, unreadable/corrupt database file, or schema incompatibility (older/newer crush writing the DB).

Common situations: Two crush instances writing sessions concurrently; crash-corrupted DB; running stats from a different user than the one who owns .crush; downgraded binary against a newer schema.

Related errors


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