siyuan-note/siyuan · warning
SQL statement is empty
Error message
SQL statement is empty
What it means
Returned by checkReadonlyStatement when the SQL string is empty after TrimSpace. This is the first guard before any SQLite prepare — it refuses to run an empty/whitespace-only statement. Used by the read-only query validation path (CheckReadonlyStatement / CheckReadonlyStatementInBox / CheckAssetContentReadonlyStatement).
Source
Thrown at kernel/sql/stmt_validate.go:188
// CheckAssetContentReadonlyStatement 在资源文件内容数据库连接上检查 SQL 是否只读。
func CheckAssetContentReadonlyStatement(stmt string) error {
return checkReadonlyStatement(stmt, assetContentDB)
}
// CheckReadonlyStatementInBox 在指定笔记本对应的数据库连接上检查 SQL 是否只读。
func CheckReadonlyStatementInBox(stmt, boxID string) error {
targetDB := db
if boxDB := GetEncryptedDB(boxID); nil != boxDB {
targetDB = boxDB
} else if IsEncryptedBoxFn != nil && IsEncryptedBoxFn(boxID) {
return errors.New("encrypted box db not opened for box " + boxID)
}
return checkReadonlyStatement(stmt, targetDB)
}
func checkReadonlyStatement(stmt string, targetDB *sql.DB) error {
if strings.TrimSpace(stmt) == "" {
return errors.New("SQL statement is empty")
}
if !isReadonlyQueryStatement(stmt) {
return errors.New("SQL statement is not a read-only query")
}
if nil == targetDB {
return errors.New("database is nil")
}
ctx := context.Background()
conn, err := targetDB.Conn(ctx)
if err != nil {
return err
}
defer conn.Close()
return conn.Raw(func(dc any) error {
sqliteConn, ok := dc.(*sqlite3.SQLiteConn)
if !ok {
return fmt.Errorf("SQL driver connection type is unexpected: %T", dc)View on GitHub (pinned to 251596fc0d)
Solutions
- Provide a non-empty SELECT/WITH query string.
- Guard the caller: skip the API call when strings.TrimSpace(stmt) == "".
- If building SQL from variables, log the rendered statement before sending to catch empty substitutions.
Example fix
// before
stmt := strings.TrimSpace(userInput)
api.QuerySQL(stmt) // errors if empty
// after
stmt := strings.TrimSpace(userInput)
if stmt == "" { return errors.New("query is required") }
api.QuerySQL(stmt) Defensive patterns
Strategy: validation
Validate before calling
// Caller side: skip empty queries before calling the SQL API.
const trimmed = stmt.trim()
if (trimmed === '') return new Error('query is required')
await api.querySQL(trimmed) Try / catch
try { await api.querySQL(stmt) }
catch (e) {
if (/statement is empty/i.test(String(e))) console.warn('skip empty SQL submission')
else throw e
} Prevention
- Trim and check for empty before submitting SQL.
- When building SQL from variables, log the rendered string to catch empty substitutions.
- Disable the submit button in the UI when the query box is empty.
When it happens
Trigger: Submitting an empty or whitespace-only SQL string ("", " ", "\n\t") to the SQL query API; a script passes an unset variable as the statement.
Common situations: UI submitted before typing; template/variable substitution produced empty string; CLI invoked with empty --stmt; trim of a comment-only statement yields empty.
Related errors
- SQL statement is not single
- SQL statement is not a read-only query
- task list item marker length should be 1
- task list item marker can not be [ or ]
- custom emoji file is too large
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/e11065f041786535.
Report an issue: GitHub.