transact-rs/sqlx · error · syn::Error
expected exactly 1 column, got {}
Error message
expected exactly 1 column, got {} What it means
The `query_scalar!` family requires the query to return exactly one column, since its output type is a single value. `quote_query_scalar` checks the described result columns and fails at compile time if the count differs, including the actual count in the message.
Source
Thrown at sqlx-macros-core/src/query/output.rs:217
#(#instantiations)*
::std::result::Result::Ok(#out_ty { #(#ident: #var_name),* })
})
}
}
pub fn quote_query_scalar<DB: DatabaseExt>(
input: &QueryMacroInput,
config: &Config,
warnings: &mut Warnings,
bind_args: &Ident,
describe: &Describe<DB>,
) -> crate::Result<TokenStream> {
let columns = describe.columns();
if columns.len() != 1 {
return Err(syn::Error::new(
input.src_span,
format!("expected exactly 1 column, got {}", columns.len()),
)
.into());
}
// attempt to parse a column override, otherwise fall back to the inferred type of the column
let ty = if let Ok(rust_col) = column_to_rust(describe, config, warnings, 0) {
rust_col.type_.to_token_stream()
} else if input.checked {
let ty = get_column_type::<DB>(config, warnings, 0, &columns[0]);
if describe.nullable(0).unwrap_or(true) {
quote! { ::std::option::Option<#ty> }
} else {
ty
}
} else {
quote! { _ }View on GitHub (pinned to 03af8bcc57)
Solutions
- Change the SQL to select exactly one column (e.g. `SELECT count(*) FROM ...`)
- If you need multiple values, use `query_as!` with a record struct instead
- If it uses a query file, fix the .sql file so it returns a single column
Example fix
// before
let names = query_scalar!("SELECT id, name FROM users").fetch_all(&pool).await?;
// after
let names = query_as!(User, "SELECT id, name FROM users").fetch_all(&pool).await?;
// or for one value:
let count: i64 = query_scalar!("SELECT count(*) FROM users").fetch_one(&pool).await?; Defensive patterns
Strategy: validation
Validate before calling
// ensure the SQL returns exactly one column before using query_scalar!
// e.g. inspect the described query in a test:
let d = sqlx::describe("SELECT count(*) FROM users", &pool).await?;
assert_eq!(d.columns().len(), 1); Prevention
- Use query_scalar! only for single-column SELECTs
- Switch to query_as! when selecting multiple columns
- Review .sql files referenced by query_scalar! when schemas/views change
- Let compile errors guide you — sqlx checks this at compile time
When it happens
Trigger: Using `query_scalar!`/`query_scalar_unchecked!` with SQL that returns 0 or 2+ columns — e.g. `SELECT id, name FROM users` or a query that returns no columns.
Common situations: Converting `query_as!` code to `query_scalar!` without trimming the select list; editing the .sql file to add a column; migrations changing a view so it now returns extra columns.
Related errors
- absolute paths will only work on the current machine
- paths relative to the current file's directory are not curre
- failed to read query file at {}: {}
- query file path cannot be represented as a string
- Cannot use both flatten and json
AI-assisted analysis of transact-rs/sqlx@03af8bcc57 (2026-09-03).
Data as JSON: /api/errors/9c63e26c7b2474bc.
Report an issue: GitHub.