{"record":{"id":"999c488fd236f3d6","repo":"charmbracelet/crush","slug":"get-usage-by-day-of-week-w","errorCode":null,"errorMessage":"get usage by day of week: %w","messagePattern":"get usage by day of week: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cmd/stats.go","lineNumber":606,"sourceCode":"\t\t})\n\t}\n\n\t// Usage by hour.\n\thourlyUsage, err := queries.GetUsageByHour(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"get usage by hour: %w\", err)\n\t}\n\tfor _, h := range hourlyUsage {\n\t\tstats.UsageByHour = append(stats.UsageByHour, HourlyUsage{\n\t\t\tHour:         int(h.Hour),\n\t\t\tSessionCount: h.SessionCount,\n\t\t})\n\t}\n\n\t// Usage by day of week.\n\tdowUsage, err := queries.GetUsageByDayOfWeek(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"get usage by day of week: %w\", err)\n\t}\n\tfor _, d := range dowUsage {\n\t\tstats.UsageByDayOfWeek = append(stats.UsageByDayOfWeek, DayOfWeekUsage{\n\t\t\tDayOfWeek:        int(d.DayOfWeek),\n\t\t\tDayName:          dayNames[int(d.DayOfWeek)],\n\t\t\tSessionCount:     d.SessionCount,\n\t\t\tPromptTokens:     nullFloat64ToInt64(d.PromptTokens),\n\t\t\tCompletionTokens: nullFloat64ToInt64(d.CompletionTokens),\n\t\t})\n\t}\n\n\t// Recent activity (last 30 days).\n\trecent, err := queries.GetRecentActivity(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"get recent activity: %w\", err)\n\t}\n\tfor _, r := range recent {\n\t\tstats.RecentActivity = append(stats.RecentActivity, DailyActivity{","sourceCodeStart":588,"sourceCodeEnd":624,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/cmd/stats.go#L588-L624","documentation":"gatherStats fetches day-of-week usage via queries.GetUsageByDayOfWeek and wraps any SQL failure with this message. It indicates the aggregate query could not run against the sessions database — access, locking, or schema issues rather than a stats-logic problem.","triggerScenarios":"GetUsageByDayOfWeek fails: SQLite locked by another writer, unreadable/corrupt DB file, or the query's expected tables/columns missing due to version/schema mismatch.","commonSituations":"Multiple crush instances; DB on an unreliable mount; partial migration after an upgrade; wrong --data-dir; DB owned by another user after a sudo run.","solutions":["Stop other crush processes and retry","Fix ownership/permissions: `chown -R $USER .crush`","Run `PRAGMA integrity_check`; restore or delete a corrupt DB","Ensure the crush binary and DB schema versions match"],"exampleFix":"// before\n-rw------- 1 root root crush.db   # run via sudo once, now unreadable\n// after\nsudo chown $USER .crush/crush.db && crush stats","handlingStrategy":"retry","validationCode":"db=\"${CRUSH_DATA_DIR:-.crush}/crush.db\"\n[ -r \"$db\" ] && [ -w \"$db\" ] && sqlite3 \"$db\" 'PRAGMA integrity_check;' | grep -q ok && echo ok || echo \"DB access/integrity problem\"","typeGuard":null,"tryCatchPattern":"if err := gatherStats(ctx, dbPath); err != nil {\n    if strings.Contains(err.Error(), \"get usage by day of week\") && errors.Is(err, os.ErrPermission) {\n        fmt.Fprintln(os.Stderr, \"Fix ownership: chown -R $USER .crush\")\n        return nil\n    }\n    return err\n}","preventionTips":["Ensure consistent file ownership of the data dir across runs","Avoid mixing sudo and normal-user invocations","Retry transient lock errors instead of immediately failing","Keep network-filesystem usage away from SQLite files","Check integrity after crashes and upgrades"],"tags":["sqlite","database","sql","cli"],"backgroundTag":"sqlite-database-locked","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}