atuinsh/atuin · error
issue in stats average query
Error message
issue in stats average query
What it means
The third stats expect() panic (database.rs:953), attached to the 'total' builder. Note the copy-paste quirk in this block: the message says 'issue in stats average query' but the line renders `total.sql()` — so if this exact panic fires, the broken builder is the totals query, despite the wording. As with the siblings, it is an internal assertion over a hard-coded query shape and is unreachable through user data or configuration.
Source
Thrown at crates/atuin-client/src/database.rs:953
.group_by("day_of_week");
// Intentionally format the string with 01 hardcoded. We want the average runtime for the
// _entire month_, but will later parse it as a datetime for sorting
// Sqlite has no datetime so we cannot do it there, and otherwise sorting will just be a
// string sort, which won't be correct.
let mut duration_over_time = SqlBuilder::select_from("history");
duration_over_time
.fields(&[
"strftime('01-%m-%Y', ROUND(timestamp / 1000000000), 'unixepoch') AS month_year",
"avg(duration) as duration",
])
.and_where("command = ?1")
.group_by("month_year")
.having("duration > 0");
let prev = prev.sql().expect("issue in stats previous query");
let next = next.sql().expect("issue in stats next query");
let total = total.sql().expect("issue in stats average query");
let average = average.sql().expect("issue in stats previous query");
let exits = exits.sql().expect("issue in stats exits query");
let day_of_week = day_of_week.sql().expect("issue in stats day of week query");
let duration_over_time = duration_over_time
.sql()
.expect("issue in stats duration over time query");
// The queries are all independent, so run them concurrently on the pool.
let (prev, next, total, average, exits, day_of_week, duration_over_time): (
_,
_,
(i64,),
(f64,),
Vec<(i64, i64)>,
Vec<(String, i64)>,
Vec<(String, f64)>,
) = tokio::try_join!(
sqlx::query(sqlx::AssertSqlSafe(prev))View on GitHub (pinned to 202f6ad98e)
Solutions
- Update Atuin and report the panic upstream — mention that the message labels are swapped on lines 953/954
- When debugging, trust the line number over the message text: database.rs:953 is the 'total' builder
- Developers: fix the label mismatch while patching (`total.sql().expect("issue in stats total query")`)
- Add rendering unit tests for all seven stats builders
Example fix
// before (label mismatch in the codebase)
let total = total.sql().expect("issue in stats average query");
// after (corrected label if patching locally)
let total = total.sql().expect("issue in stats total query"); Defensive patterns
Strategy: validation
Try / catch
let handle = std::thread::spawn(move || db.stats());
match handle.join() {
Ok(Ok(s)) => { /* stats */ }
Err(_) => { /* internal panic on line 953 = 'total' builder (label is swapped); report upstream */ }
} Prevention
- When debugging, map line numbers to builders, not message text (953=total, 954=average)
- Fix the swapped expect labels when patching stats code locally
- Unit-test rendering of the total query separately
- Report upstream occurrences with backtrace line numbers
When it happens
Trigger: Running `atuin stats` on a build where the 'total' builder construction was broken; the misleading message means you should look at the `total` builder, not `average`, when debugging.
Common situations: Development regressions in the stats feature; the swapped labels (line 953/954) can send a debugger to the wrong builder, so awareness of the mismatch matters.
Related errors
- issue in stats previous query
- issue in stats next query
- issue in stats exits query
- issue in stats duration over time query
- bug in list query. please report
AI-assisted analysis of atuinsh/atuin@202f6ad98e (2026-08-16).
Data as JSON: /api/errors/b99823278ad9a62c.
Report an issue: GitHub.