{"record":{"id":"498e6e046d2ce47b","repo":"t8y2/dbx","slug":"tdengine-query-returned-no-rows","errorCode":null,"errorMessage":"TDengine query returned no rows","messagePattern":"TDengine query returned no rows","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/tdengine/src/driver.rs","lineNumber":770,"sourceCode":"        execution_time_ms: 0,\n        truncated: false,\n        session_id: None,\n        has_more: false,\n    })\n}\n\nasync fn query_scalar_string(\n    connection: &Taos,\n    sql: &str,\n    token: &CancellationToken,\n    timeout_secs: u64,\n) -> Result<String> {\n    let mut result = cancellable(token, timeout_secs, connection.query(sql)).await?;\n    let timezone = result.timezone();\n    loop {\n        let block = cancellable(token, timeout_secs, poll_fn(|context| result.fetch_raw_block(context))).await?;\n        let Some(block) = block else {\n            bail!(\"TDengine query returned no rows\");\n        };\n        if block.nrows() == 0 || block.ncols() == 0 {\n            continue;\n        }\n        let value = block.get_ref(0, 0).ok_or_else(|| anyhow!(\"TDengine query returned an empty value\"))?;\n        return match borrowed_value_to_json(value, preferred_timezone(timezone, block.timezone(), None)) {\n            Value::String(value) => Ok(value),\n            value => Ok(value.to_string()),\n        };\n    }\n}\n\nfn preferred_timezone(\n    query_timezone: Option<Tz>,\n    block_timezone: Option<Tz>,\n    session_timezone: Option<Tz>,\n) -> Option<Tz> {\n    query_timezone.or(block_timezone).or(session_timezone)","sourceCodeStart":752,"sourceCodeEnd":788,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/tdengine/src/driver.rs#L752-L788","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nlet v = query_scalar_string(conn, \"SELECT value FROM config WHERE id=42\", ...).await?;\n// after\nlet v = query_scalar_string(conn, \"SELECT COALESCE(MAX(value), 'default') FROM config WHERE id=42\", ...).await?;","handlingStrategy":"fallback","validationCode":"// prefer queries guaranteed to return one row\nlet sql = \"SELECT COALESCE(MAX(value), '') FROM t WHERE id=42\";","typeGuard":null,"tryCatchPattern":"match query_scalar_string(conn, sql, &token, timeout).await {\n    Err(e) if e.to_string().contains(\"no rows\") => Ok(String::new()), // default\n    other => other,\n}","preventionTips":["Use aggregate functions for scalar lookups","Handle empty tables explicitly","Use query_rows when zero rows is expected"],"tags":["rust","tdengine","empty-result","scalar-query","health-check"],"backgroundTag":"empty-result-set","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}