tursodatabase/turso · error · NotSupportedException

SQLite native handles are not available for direct remote co

Error message

SQLite native handles are not available for direct remote connections.

What it means

This NotSupportedException is thrown by the native-handle getter when the connection wraps a managed TursoConnection but is not an embedded replica. Direct remote connections have no local SQLite database handle to expose, so native-handle APIs cannot work.

Source

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

            {
                NotifyManagedStateChange(originalState);
            }
        }

        _disposed = true;
        await base.DisposeAsync().ConfigureAwait(false);
        failure?.Throw();
    }

    internal TursoDatabaseHandle DatabaseHandle
    {
        get
        {
            if (_managedConnection is not null)
            {
                if (IsReplica)
                    return ManagedConnection.Turso;
                throw new NotSupportedException(
                    "SQLite native handles are not available for direct remote connections.");
            }

            return _database ?? throw new InvalidOperationException("The connection is not open.");
        }
    }

    internal bool HasOpenReader => _openReaderCount > 0;

    internal bool IsReadOnly => _readOnly;

    internal bool RecursiveTriggers => _recursiveTriggers;

    internal bool ManagedReadYourWrites => _connectionOptions.ReadYourWrites;

    internal void ReaderOpened() => _openReaderCount++;

    internal void ReaderClosed()

View on GitHub (pinned to 6c72522679)

Solutions

  1. Use an embedded replica connection if you need native handles plus remote data
  2. Perform the interop operation against a local SqliteConnection instead of a direct remote wrapper
  3. Use the managed API surface (TursoConnection.Turso) directly for remote operations rather than native handles
  4. Branch on IsManagedConnection/IsReplica before requesting the handle

Example fix

// before
var handle = remoteWrapper.Handle; // throws: direct remote

// after
if (remoteWrapper.IsManagedConnection && remoteWrapper.IsReplica)
{
    var turso = remoteWrapper.ManagedConnection.Turso;
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (conn.IsManagedConnection && !conn.IsReplica) return UseManagedApi(conn);

Type guard

bool NativeHandleAvailable(SqliteConnection c) => !c.IsManagedConnection || c.IsReplica;

Try / catch

try { return conn.Handle; }
catch (NotSupportedException ex) when (ex.Message.Contains("native handles"))
{
    return null; // managed path only
}

Prevention

When it happens

Trigger: Accessing the connection's native handle property (e.g. Handle or an internal accessor used by extensions/interop) on a SqliteConnection wrapping a direct remote TursoConnection; the code path returns ManagedConnection.Turso only for replicas and otherwise throws.

Common situations: Interop code (e.g. sqlite3_* P/Invoke, backup, custom functions) written for local connections being applied to a direct remote wrapper; third-party libraries requesting the native handle generically.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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