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
- Close the connection before assigning a new ConnectionString, then reopen.
- Prefer constructing a new SqliteConnection with the new string instead of mutating an existing one.
- 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
- Treat ConnectionString as construct-time configuration: 'new SqliteConnection(cs)'.
- On config reload, build new connection objects instead of mutating live ones.
- Add a debug assertion that ConnectionString is only assigned when State == Closed.
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
- Encryption is not supported by {libraryName}.
- {method} requires an open connection.
- The connection is already open.
- Changing databases is not supported.
- The connection is not open.
AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-09-06).
Data as JSON: /api/errors/cdd9aaad19c72f55.
Report an issue: GitHub.