atuinsh/atuin · error
issue in stats previous query
Error message
issue in stats previous query
What it means
One of seven expect() panics in the stats code (database.rs:951) that render the 'prev' SqlBuilder for Atuin's `atuin stats` command. The builders for prev/next/total/average/exits/day_of_week/duration_over_time are all fixed-shape SELECTs over the history table; sql() failing means the builder was left in an invalid state by a code change. Because the query shape is hard-coded, no user input, database size, or settings value can cause this — it is purely an internal regression guard.
Source
Thrown at crates/atuin-client/src/database.rs:951
])
.and_where("command = ?1")
.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)>,View on GitHub (pinned to 202f6ad98e)
Solutions
- Update to the latest Atuin release — this is an internal assertion, not a data problem
- Report upstream with the exact panic message and version
- Developers: after editing any stats builder, run `atuin stats` locally as a smoke test
- Cover each stats builder with a unit test asserting .sql().is_ok()
Defensive patterns
Strategy: validation
Try / catch
// expect() panic: isolate if needed
let handle = std::thread::spawn(move || db.stats());
match handle.join() {
Ok(Ok(s)) => { /* stats */ }
Ok(Err(e)) => { /* db error */ }
Err(_) => { /* internal stats-query panic: report upstream */ }
} Prevention
- Run `atuin stats` as a smoke test after any local build touching database.rs
- Unit-test that every stats builder renders (.sql().is_ok())
- Keep stats builder shapes fixed unless a migration demands change
- Report sightings upstream — no user data can trigger this
When it happens
Trigger: Running `atuin stats` (which builds all seven builders and renders them back-to-back); the panic itself only triggers after someone edited one of the builder constructions into an unrenderable state.
Common situations: Seen only during Atuin development around the stats feature; users hitting it should suspect a corrupted custom build or a genuinely new upstream bug and report it.
Related errors
- issue in stats next query
- issue in stats average 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/984f5fe21f441111.
Report an issue: GitHub.