tursodatabase/turso · error · SqliteException

throw ToSqliteException(ex, statement.Sql);

Error message

throw ToSqliteException(ex, statement.Sql);

What it means

When SqliteCommand.Prepare() or PrepareAsync() is called on a managed (remote/embedded) command, any TursoException raised while compiling the SQL statement is converted into a standard Microsoft.Data.Sqlite SqliteException with mapped SQLite result codes. This wrapper exists so ADO.NET callers see the familiar exception type instead of a Turso-specific one. The failing SQL text is preserved for diagnostics.

Source

Thrown at bindings/dotnet/src/Turso.Data.Sqlite/SqliteCommand.cs:347

    private async Task PrepareManagedAsync(CancellationToken cancellationToken)
    {
        var statements = GetManagedStatements();
        ValidateManagedParameterValues();
        foreach (var statement in statements)
        {
            cancellationToken.ThrowIfCancellationRequested();
            var sql = RewriteFacadeStatement(statement.Sql, Connection!);

            using var command = CreateManagedCommand(statement, sql);
            _activeManagedCommand = command;
            try
            {
                await command.PrepareAsync(cancellationToken).ConfigureAwait(false);
            }
            catch (TursoException ex)
            {
                throw ToSqliteException(ex, statement.Sql);
            }
            finally
            {
                _activeManagedCommand = null;
            }
        }
    }

    private async Task<SqliteDataReader> ExecuteManagedAsync(
        string method,
        CommandBehavior behavior,
        CancellationToken cancellationToken)
    {
        EnsureExecutable(method);
        var statements = GetManagedStatements();
        if (Connection!.HasOpenReader && statements.Any(IsWriteStatement))
        {
            await Task.Delay(TimeSpan.FromSeconds(CommandTimeout), cancellationToken).ConfigureAwait(false);

View on GitHub (pinned to 6c72522679)

Solutions

  1. Read the SqliteException message/SqliteErrorCode to identify the actual SQL problem (parse error, no such table, etc.) and fix the SQL or schema.
  2. Call Prepare() only after the schema exists; run migrations before command preparation.
  3. If the cause is a dead connection, check Connection.State and reopen/refresh the connection.
  4. Catch SqliteException and inspect SqliteErrorCode (e.g. SQLITE_ERROR 1) for programmatic handling.

Example fix

// before
await cmd.PrepareAsync(ct); // throws SqliteException 'no such table: users'
// after
await EnsureTablesExistAsync(conn); // run DDL/migrations first
await cmd.PrepareAsync(ct);
Defensive patterns

Strategy: try-catch

Validate before calling

if (conn.State != ConnectionState.Open) throw new InvalidOperationException("connection must be open before Prepare");
// additionally: ensure schema exists, e.g. SELECT name FROM sqlite_master WHERE name = 'mytable'

Type guard

static bool CanPrepare(SqliteCommand cmd) =>
    cmd?.Connection is SqliteConnection c && c.State == ConnectionState.Open && !string.IsNullOrWhiteSpace(cmd.CommandText);

Try / catch

try
{
    await cmd.PrepareAsync(ct);
}
catch (SqliteException ex)
{
    // ex.SqliteErrorCode: 1 = SQL/syntax/missing object, 5 = busy, 7 = out of memory
    logger.LogError(ex, "Prepare failed for: {Sql}", cmd.CommandText);
    throw;
}

Prevention

When it happens

Trigger: Calling Prepare()/PrepareAsync() on a SqliteCommand whose SQL contains a syntax error, references a missing table/column, or whose underlying Turso connection/stream has failed; the inner command.PrepareAsync call throws TursoException.

Common situations: Typos in SQL, running a query before migrations created the table, schema drift between environments, or a remote connection dropped between opening the connection and preparing the statement.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-09-06). Data as JSON: /api/errors/dba9b38c20cfdd78. Report an issue: GitHub.