tursodatabase/turso · error · InvalidOperationException

The connection string can only be set when the connection is

Error message

The connection string can only be set when the connection is closed.

What it means

Assigning SqliteConnection.ConnectionString throws InvalidOperationException when State is Open, because the options encoded in the string (data source, mode, pragmas) have already been applied to the live database handle and cannot be swapped underneath it. The setter only accepts a new string on a closed connection. This mirrors Microsoft.Data.Sqlite behavior and prevents silently diverging connection state.

Source

Thrown at bindings/dotnet/src/Turso.Data.Sqlite/SqliteConnection.cs:69

                "Only direct remote and embedded replica Turso connections can be wrapped.",
                nameof(connection));
        }

        _connectionOptions = options;
        _managedConnection = connection;
        _ownsManagedConnection = ownsConnection;
        _wrapsManagedConnection = true;
        _readOnly = options.Mode == SqliteOpenMode.ReadOnly;
    }

    [AllowNull]
    public override string ConnectionString
    {
        get => _connectionOptions.ConnectionString;
        set
        {
            if (State == ConnectionState.Open)
                throw new InvalidOperationException(Properties.Resources.ConnectionStringRequiresClosedConnection);

            var options = new SqliteConnectionStringBuilder(value);
            if (_wrapsManagedConnection && options.IsLocal)
            {
                throw new InvalidOperationException(
                    "A SqliteConnection wrapping a TursoConnection must remain a direct remote or embedded replica connection.");
            }

            ConfigureManagedConnection(options);
            _connectionOptions = options;
            _defaultTimeout = null;
        }
    }

    public override string Database => _managedConnection?.Database ?? "main";

    public override string DataSource => _managedConnection?.DataSource ?? _dataSource ?? _connectionOptions.DataSource;

View on GitHub (pinned to 6c72522679)

Solutions

  1. Close the connection before assigning a new ConnectionString, then reopen.
  2. Prefer constructing a new SqliteConnection with the new string instead of mutating an existing one.
  3. Set the connection string once at construction ('new SqliteConnection(cs)') and treat it as immutable.

Example fix

// before
var conn = new SqliteConnection(cs1);
conn.Open();
conn.ConnectionString = cs2; // throws: can only be set when closed

// after
var conn = new SqliteConnection(cs1);
conn.Open();
conn.Close();
conn.ConnectionString = cs2;
conn.Open();
Defensive patterns

Strategy: validation

Validate before calling

static void SafeSetConnectionString(SqliteConnection conn, string cs)
{
    if (conn.State != ConnectionState.Closed)
        conn.Close();
    conn.ConnectionString = cs;
}

Try / catch

null

Prevention

When it happens

Trigger: 'conn.Open(); conn.ConnectionString = newCs;' in code that reconfigures connections in place; config-reload logic that pushes a fresh connection string into an existing open connection; helper factories that set properties on a shared, already-open connection object.

Common situations: DI singletons that get restarted settings without recreating the connection, hot-reload of appsettings while pooled/open connections exist, and test suites mutating one connection across test cases.

Related errors


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