t8y2/dbx · error
TDengine query returned no rows
Error message
TDengine query returned no rows
What it means
query_scalar_string executes a statement expected to return exactly a scalar (used by connect/validate_connection for version/health checks). When the server returns zero rows (fetch_raw_block yields None), the driver errors because there is no scalar to return. Note: a block with 0 rows or 0 columns is skipped and the loop keeps polling until exhaustion.
Source
Thrown at agents/drivers/tdengine/src/driver.rs:770
execution_time_ms: 0,
truncated: false,
session_id: None,
has_more: false,
})
}
async fn query_scalar_string(
connection: &Taos,
sql: &str,
token: &CancellationToken,
timeout_secs: u64,
) -> Result<String> {
let mut result = cancellable(token, timeout_secs, connection.query(sql)).await?;
let timezone = result.timezone();
loop {
let block = cancellable(token, timeout_secs, poll_fn(|context| result.fetch_raw_block(context))).await?;
let Some(block) = block else {
bail!("TDengine query returned no rows");
};
if block.nrows() == 0 || block.ncols() == 0 {
continue;
}
let value = block.get_ref(0, 0).ok_or_else(|| anyhow!("TDengine query returned an empty value"))?;
return match borrowed_value_to_json(value, preferred_timezone(timezone, block.timezone(), None)) {
Value::String(value) => Ok(value),
value => Ok(value.to_string()),
};
}
}
fn preferred_timezone(
query_timezone: Option<Tz>,
block_timezone: Option<Tz>,
session_timezone: Option<Tz>,
) -> Option<Tz> {
query_timezone.or(block_timezone).or(session_timezone)View on GitHub (pinned to c0390bff16)
Solutions
- Fix the scalar query to always return one row (e.g. use aggregates: SELECT COUNT(*) FROM ... or SELECT FIRST(value) ...)
- Use execute_query/query_rows instead if zero rows is an expected outcome
- Guard the caller: treat 'no rows' as a distinct result rather than routing it through the scalar helper
Example fix
// before let v = query_scalar_string(conn, "SELECT value FROM config WHERE id=42", ...).await?; // after let v = query_scalar_string(conn, "SELECT COALESCE(MAX(value), 'default') FROM config WHERE id=42", ...).await?;
Defensive patterns
Strategy: fallback
Validate before calling
// prefer queries guaranteed to return one row let sql = "SELECT COALESCE(MAX(value), '') FROM t WHERE id=42";
Try / catch
match query_scalar_string(conn, sql, &token, timeout).await {
Err(e) if e.to_string().contains("no rows") => Ok(String::new()), // default
other => other,
} Prevention
- Use aggregate functions for scalar lookups
- Handle empty tables explicitly
- Use query_rows when zero rows is expected
When it happens
Trigger: Running a scalar query that matches no rows — e.g. SELECT value FROM meta WHERE key='x' with no such row, or an empty table — via query_scalar_string during connect or validate_connection.
Common situations: Health-check queries against a fresh/empty database, mistyped metadata keys, or a database/user without the queried object so the query legitimately returns no rows.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- TDengine Rust WebSocket connector does not support client ce
- TDengine native agent supports only WebSocket connection str
- TDengine query session not found: {session_id}
- SQL is required
- TDengine operation was cancelled
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/498e6e046d2ce47b.
Report an issue: GitHub.