atuinsh/atuin · error
bug in search query. please report
Error message
bug in search query. please report
What it means
A panic in Database::search when SqlBuilder::sql() fails to render the inner query used for full-text search pagination. The builder assembles the FTS match, context filters, the optional 'after' timestamp bound, author/shell filters, and deleted_at IS NULL, then embeds the rendered SQL twice as a derived table (which is why it must render cleanly and without positional parameters). The expect fires only when builder misuse leaves it in an unrenderable state — an Atuin code bug, not something user data or settings can trigger.
Source
Thrown at crates/atuin-client/src/database.rs:766
}
if let Some(after) = filter_options.after {
let parsed =
interim::parse_date_string(after, OffsetDateTime::now_utc(), interim::Dialect::Uk)
.map_err(|e| {
sqlx::Error::Decode(format!("invalid `after` filter {after:?}: {e}").into())
})?;
sql.and_where_gt("timestamp", quote(parsed.unix_timestamp_nanos() as i64));
}
apply_author_filter(&mut sql, filter_options.authors);
apply_shell_filter(&mut sql, filter_options.shells);
sql.and_where_is_null("deleted_at");
// sql_builder inlines every bound value, so the inner query carries no
// positional parameters and is safe to embed (twice) as a derived table.
let inner = sql.sql().expect("bug in search query. please report");
let inner = inner.trim().trim_end_matches(';');
let order = if filter_options.reverse {
"ASC"
} else {
"DESC"
};
let tail = match (filter_options.limit, filter_options.offset) {
(Some(limit), Some(offset)) => format!(" LIMIT {limit} OFFSET {offset}"),
(Some(limit), None) => format!(" LIMIT {limit}"),
// SQLite requires a LIMIT before OFFSET; -1 means "no limit".
(None, Some(offset)) => format!(" LIMIT -1 OFFSET {offset}"),
(None, None) => String::new(),
};
// Deduplicate by keeping, for each command, only its most recent entry
// within the filtered set. Expressed as a correlated NOT EXISTS ratherView on GitHub (pinned to 202f6ad98e)
Solutions
- Update Atuin if you hit this as a user — the message means an internal bug, please report it with the stack trace
- Developers: unit-test sql() rendering for every filter_options permutation before fetch
- Keep bound values inlined via quote()/helpers so the derived-table embedding stays parameter-free, as the comment requires
- Reproduce with a fixed seed database and bisect the filter that breaks rendering
Example fix
// before (development cause): a filter adds a positional param
sql.and_where("timestamp > ?");
// after: inline the value as the codebase does
sql.and_where_gt("timestamp", quote(parsed.unix_timestamp_nanos() as i64)); Defensive patterns
Strategy: validation
Try / catch
// expect() panic: contain it only by isolating the call, e.g. a spawned thread:
let handle = std::thread::spawn(move || db.search(query, filter_options));
match handle.join() {
Ok(Ok(rows)) => { /* use rows */ }
Ok(Err(e)) => { /* sqlx error */ }
Err(_) => { /* internal invariant panic — report upstream */ }
} Prevention
- Update Atuin and report the panic; it marks an internal regression, not misuse
- Developers: keep all bound values inlined (quote()) so the derived-table embedding stays parameter-free
- Unit-test rendering of the inner query for every filter_options permutation
- Smoke-test search with each filter (host/session/directory/workspace) after local builds
When it happens
Trigger: Calling Database::search with any query/filter_options combination; the panic requires a regression such as a new filter helper that invalidates the builder or leaves positional '?' placeholders (which the comment warns the derived-table embedding cannot tolerate).
Common situations: Hit by Atuin developers extending search filters (authors/shells/after were recent additions) whose helper mutates the builder incorrectly; never observed from config in released builds.
Related errors
- bug in list query. please report
- issue in stats previous query
- issue in stats next query
- issue in stats average query
- issue in stats exits query
AI-assisted analysis of atuinsh/atuin@202f6ad98e (2026-08-16).
Data as JSON: /api/errors/2acb5356f80c99f2.
Report an issue: GitHub.