t8y2/dbx · warning

SQL is empty

Error message

SQL is empty

What it means

The worker's query() rejects SQL that is empty or whitespace-only after trimming, before attempting to parse or execute it. This avoids handing a blank statement to SQLite and gives a clear error instead of a parser complaint.

Source

Thrown at crates/dbx-sqlite-worker/src/runtime.rs:86

    if path.trim().is_empty() {
        return Err("SQLite path is empty".to_string());
    }
    if path.contains('\0') {
        return Err("SQLite path contains NUL".to_string());
    }
    let flags = OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_URI;
    if !Path::new(path).is_file() {
        return Err(format!("File does not exist: {path}"));
    }
    let conn = Connection::open_with_flags(path, flags).map_err(|e| format!("failed to open SQLite file: {e}"))?;
    conn.busy_timeout(Duration::from_secs(10)).map_err(|e| e.to_string())?;
    Ok(conn)
}

fn query(conn: &Connection, sql: &str, max_rows: usize) -> WorkerBody {
    let trimmed = sql.trim();
    if trimmed.is_empty() {
        return WorkerBody::err("SQL is empty");
    }
    if sqlite_statement_returns_rows(trimmed) {
        query_statement(conn, trimmed, max_rows)
    } else {
        match conn.execute_batch(trimmed) {
            Ok(()) => WorkerBody::query(Vec::new(), Vec::new(), Vec::new(), conn.changes(), false),
            Err(error) => WorkerBody::err(error.to_string()),
        }
    }
}

fn sqlite_statement_returns_rows(sql: &str) -> bool {
    if sqlite_starts_with_keyword(sql, &["SELECT", "PRAGMA", "EXPLAIN", "WITH"]) {
        return true;
    }
    let Ok(statements) = Parser::parse_sql(&SQLiteDialect {}, sql) else {
        return false;
    };

View on GitHub (pinned to c0390bff16)

Solutions

  1. Non-empty SQL before sending: check sql.trim().is_empty() on the caller side
  2. Fix query-building logic that interpolates to an empty string
  3. If reading SQL from a file/config, validate the content is loaded
  4. Log or surface the input source so blank queries are caught in dev

Example fix

// before
let sql = std::env::var("SQL").unwrap_or_default();
worker.query(&sql)?; // "" -> SQL is empty
// after
let sql = std::env::var("SQL")?;
assert!(!sql.trim().is_empty(), "SQL must not be blank");
worker.query(&sql)?;
Defensive patterns

Strategy: validation

Validate before calling

fn require_non_empty_sql(sql: &str) -> Result<&str, &'static str> {
    let t = sql.trim();
    if t.is_empty() { Err("SQL is empty") } else { Ok(t) }
}

Type guard

fn is_executable_sql(sql: &str) -> bool { !sql.trim().is_empty() }

Try / catch

match worker.send(WorkerOp::Query { sql: sql.to_string(), max_rows: None }).await {
    Err(body) if body.error() == Some("SQL is empty") => {
        eprintln!("Query text was blank; check the query builder/input source");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling the Query op with sql = "", " ", or only newlines/comments after trim; a template interpolation that produced an empty string; UI sending an unsaved/blank editor buffer.

Common situations: Programmatic query builders emitting nothing when filters are empty; reading SQL from an empty file or unset env var; copy-paste losing the query text.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/a9c96ad7ce510aff. Report an issue: GitHub.