atuinsh/atuin · error

bug in list query. please report

Error message

bug in list query. please report

What it means

A panic (std::io::Error::expect-style assertion) in Database::list when sql_builder's SqlBuilder::sql() fails to render the constructed SELECT. The builder was driven through filters (Global/Host/Session/SessionPreload/Directory/Workspace), optional group_by/having for unique, limit, and the inclusive timestamp range — and rendering still failed. sql() only errors when the builder is in an invalid state (e.g. no table, empty projection), which no combination of the public arguments can produce; the message literally asks you to report it because it indicates a bug in Atuin itself.

Source

Thrown at crates/atuin-client/src/database.rs:563

            };
        }

        if unique {
            query.group_by("command").having("max(timestamp)");
        }

        if let Some(max) = max {
            query.limit(max);
        }

        // Inclusive on both ends, matching `range()`. `stats` relies on this to count a
        // command recorded exactly on a period boundary (e.g. at midnight).
        if let Some((from, to)) = range {
            query.and_where_ge("timestamp", from.unix_timestamp_nanos() as i64);
            query.and_where_le("timestamp", to.unix_timestamp_nanos() as i64);
        }

        let query = query.sql().expect("bug in list query. please report");

        let res = sqlx::query(sqlx::AssertSqlSafe(query))
            .map(Self::query_history)
            .fetch_all(&self.pool)
            .await?;

        Ok(res)
    }

    async fn range(&self, from: OffsetDateTime, to: OffsetDateTime) -> Result<Vec<History>> {
        debug!("listing history from {:?} to {:?}", from, to);

        let res = sqlx::query(
            "select * from history where timestamp >= ?1 and timestamp <= ?2 order by timestamp asc",
        )
        .bind(from.unix_timestamp_nanos() as i64)
        .bind(to.unix_timestamp_nanos() as i64)
            .map(Self::query_history)

View on GitHub (pinned to 202f6ad98e)

Solutions

  1. If you are a user: update Atuin — this is an internal bug, not a configuration problem
  2. Report it upstream (github.com/atuinsh/atuin issues) with the panic backtrace and the atuin version
  3. If you are developing: bisect your changes to the query construction in list() and test each builder mutation with .sql() before chaining further
  4. Add a unit test covering the exact filter combination that panicked

Example fix

// before (development-time cause): a filter arm forgets to keep the builder valid
FilterMode::Global => &mut query,
// after: ensure every arm returns the same, still-valid builder and smoke-test rendering
let sql = query.sql().expect("bug in list query. please report");
Defensive patterns

Strategy: validation

Try / catch

// Panic via expect(): not catchable as a normal error. In embedding code, run the
// query on a thread and treat a join error as 'internal bug' if you must contain it:
let handle = std::thread::spawn(move || db.list(&filters, &ctx, max, unique, false, None));
match handle.join() {
    Ok(Ok(rows)) => { /* use rows */ }
    Ok(Err(e)) => { /* database error */ }
    Err(_) => { /* panicked: internal invariant — report upstream */ }
}

Prevention

When it happens

Trigger: Calling Database::list with any combination of filters/max/unique/range — the panic path requires a code regression, such as a filter arm forgetting select_from or adding an invalid SqlName/field. It is not reachable via user config or data.

Common situations: Virtually never seen in released builds; appears when developing Atuin and adding a new FilterMode or query clause that breaks the builder, or after a refactor drops a required builder step.

Related errors


AI-assisted analysis of atuinsh/atuin@202f6ad98e (2026-08-16). Data as JSON: /api/errors/3c3579445fbe8c16. Report an issue: GitHub.